better-ts-stack 2.1.0 → 2.1.2

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.
Files changed (107) hide show
  1. package/LICENSE +21 -21
  2. package/dist/args.js +9 -0
  3. package/dist/builder/configGenerator.js +3 -1
  4. package/dist/builder/moduleSelector.js +8 -1
  5. package/dist/builder/readmeGenerator.js +12 -0
  6. package/dist/builder/templateContext.js +24 -0
  7. package/dist/output/nextSteps.js +4 -0
  8. package/dist/prompts/index.js +3 -1
  9. package/dist/prompts/stack.js +9 -0
  10. package/dist/types/index.js +3 -0
  11. package/dist/ui/messages.js +3 -0
  12. package/package.json +71 -71
  13. package/templates/backend/express/.prettierignore +52 -52
  14. package/templates/backend/express/.prettierrc +16 -16
  15. package/templates/backend/express/config.json +8 -8
  16. package/templates/backend/express/gitignore +6 -1
  17. package/templates/backend/express/tsconfig.eslint.json +9 -9
  18. package/templates/backend/nestjs/.prettierignore +52 -52
  19. package/templates/backend/nestjs/config.json +10 -10
  20. package/templates/backend/nestjs/gitignore +6 -1
  21. package/templates/backend/nestjs/src/app.module.ts.hbs +1 -1
  22. package/templates/backend/nestjs/src/health/{health.controller.ts → health.controller.ts.hbs} +8 -0
  23. package/templates/backend/nestjs/tsconfig.eslint.json +9 -9
  24. package/templates/frontend/nextjs/app/globals.css +89 -89
  25. package/templates/frontend/nextjs/app/layout.tsx +34 -34
  26. package/templates/frontend/nextjs/components/ui/button.tsx +51 -51
  27. package/templates/frontend/nextjs/components/ui/card.tsx +60 -60
  28. package/templates/frontend/nextjs/components/ui/field.tsx +67 -67
  29. package/templates/frontend/nextjs/components/ui/input.tsx +18 -18
  30. package/templates/frontend/nextjs/config.json +35 -37
  31. package/templates/frontend/nextjs/eslint.config.mjs +11 -11
  32. package/templates/frontend/nextjs/gitignore +3 -0
  33. package/templates/frontend/nextjs/next.config.ts.hbs +12 -12
  34. package/templates/frontend/nextjs/postcss.config.mjs +7 -7
  35. package/templates/frontend/nextjs/public/file.svg +1 -1
  36. package/templates/frontend/nextjs/public/globe.svg +1 -1
  37. package/templates/frontend/nextjs/public/window.svg +1 -1
  38. package/templates/frontend/tanstack/components.json +18 -18
  39. package/templates/frontend/tanstack/config.json +15 -15
  40. package/templates/frontend/tanstack/eslint.config.mjs +23 -23
  41. package/templates/frontend/tanstack/gitignore +42 -39
  42. package/templates/frontend/tanstack/public/favicon.svg +7 -7
  43. package/templates/frontend/tanstack/src/components/ui/button.tsx +51 -51
  44. package/templates/frontend/tanstack/src/components/ui/card.tsx +60 -60
  45. package/templates/frontend/tanstack/src/components/ui/field.tsx +67 -67
  46. package/templates/frontend/tanstack/src/components/ui/input.tsx +18 -18
  47. package/templates/frontend/tanstack/src/lib/utils.ts +6 -6
  48. package/templates/frontend/tanstack/src/router.tsx +31 -31
  49. package/templates/frontend/tanstack/src/routes/__root.tsx +69 -69
  50. package/templates/frontend/tanstack/tsconfig.json +22 -22
  51. package/templates/frontend/tanstack/vite.config.ts +5 -4
  52. package/templates/modules/agents/AGENTS.md.hbs +237 -0
  53. package/templates/modules/agents/CLAUDE.md +1 -0
  54. package/templates/modules/agents/config.json +10 -0
  55. package/templates/modules/auth/express/config.json +1 -1
  56. package/templates/modules/auth/express/src/lib/jwt.ts.hbs +27 -27
  57. package/templates/modules/auth/express/src/middleware/requireAuth.ts.hbs +1 -2
  58. package/templates/modules/auth/nestjs/config.json +1 -1
  59. package/templates/modules/auth/nextjs/app/api/auth/[...all]/route.ts +4 -4
  60. package/templates/modules/auth/nextjs/config.json +18 -18
  61. package/templates/modules/auth/nextjs/lib/auth-client.ts +3 -3
  62. package/templates/{frontend/nextjs/proxy.ts.hbs → modules/auth/nextjs/proxy.ts} +1 -8
  63. package/templates/modules/auth/tanstack/config.json +18 -18
  64. package/templates/modules/auth/tanstack/src/lib/auth-client.ts +2 -2
  65. package/templates/modules/auth/tanstack/src/lib/auth-functions.ts +8 -8
  66. package/templates/modules/auth/tanstack/src/lib/auth.ts.hbs +37 -37
  67. package/templates/modules/auth/tanstack/src/routes/api/auth/$.ts +15 -15
  68. package/templates/modules/auth/tanstack/src/routes/dashboard.tsx +110 -110
  69. package/templates/modules/auth/tanstack/src/routes/sign-in.tsx +36 -36
  70. package/templates/modules/auth/tanstack/src/routes/sign-up.tsx +36 -36
  71. package/templates/modules/ci/.github/workflows/ci.yml.hbs +43 -0
  72. package/templates/modules/ci/config.json +10 -0
  73. package/templates/modules/docker/.dockerignore +3 -0
  74. package/templates/modules/docker/config.json +15 -15
  75. package/templates/modules/docker/docker-compose.yml.hbs +1 -1
  76. package/templates/modules/drizzle/express/config.json +26 -26
  77. package/templates/modules/drizzle/nestjs/config.json +26 -26
  78. package/templates/modules/drizzle/nextjs/config.json +26 -26
  79. package/templates/modules/drizzle/nextjs/drizzle.config.ts +13 -13
  80. package/templates/modules/drizzle/tanstack/config.json +26 -26
  81. package/templates/modules/drizzle/tanstack/drizzle.config.ts +12 -12
  82. package/templates/modules/drizzle/tanstack/src/lib/db.ts +13 -13
  83. package/templates/modules/mongoose/express/config.json +15 -15
  84. package/templates/modules/mongoose/express/src/lib/db.ts +43 -43
  85. package/templates/modules/mongoose/express/src/models/User.ts +48 -48
  86. package/templates/modules/mongoose/nestjs/config.json +15 -15
  87. package/templates/modules/mongoose/nextjs/config.json +15 -15
  88. package/templates/modules/mongoose/nextjs/models/User.ts +48 -48
  89. package/templates/modules/mongoose/tanstack/config.json +16 -16
  90. package/templates/modules/mongoose/tanstack/src/models/User.ts +48 -48
  91. package/templates/modules/prisma/express/config.json +27 -27
  92. package/templates/modules/prisma/express/prisma/schema.prisma +23 -23
  93. package/templates/modules/prisma/express/prisma.config.ts +4 -2
  94. package/templates/modules/prisma/nestjs/config.json +27 -27
  95. package/templates/modules/prisma/nestjs/prisma.config.ts +4 -2
  96. package/templates/modules/prisma/nextjs/config.json +28 -28
  97. package/templates/modules/prisma/nextjs/lib/prisma.ts +18 -18
  98. package/templates/modules/prisma/nextjs/prisma.config.ts +14 -12
  99. package/templates/modules/prisma/tanstack/config.json +28 -28
  100. package/templates/modules/prisma/tanstack/prisma/schema.prisma.hbs +91 -91
  101. package/templates/modules/prisma/tanstack/prisma.config.ts +14 -12
  102. package/templates/modules/prisma/tanstack/src/lib/prisma.ts +17 -17
  103. package/templates/modules/rate-limit/express/config.json +1 -1
  104. package/templates/modules/rate-limit/express/src/middleware/rateLimit.ts +3 -1
  105. package/templates/modules/vscode/.vscode/extensions.json.hbs +29 -0
  106. package/templates/modules/vscode/.vscode/settings.json.hbs +22 -0
  107. package/templates/modules/vscode/config.json +10 -0
@@ -1,52 +1,52 @@
1
- # Dependencies
2
- node_modules
3
- **/node_modules
4
-
5
- # Build outputs
6
- .next
7
- out
8
- dist
9
- build
10
- **/dist
11
- **/.next
12
- **/out
13
- **/build
14
-
15
- # Generated files
16
- *.min.js
17
- *.min.css
18
- coverage
19
- .nyc_output
20
-
21
- # Lock files
22
- package-lock.json
23
- yarn.lock
24
- pnpm-lock.yaml
25
- bun.lock
26
-
27
- # Logs
28
- *.log
29
- npm-debug.log*
30
- yarn-debug.log*
31
- yarn-error.log*
32
-
33
- # Environment files
34
- .env
35
- .env.local
36
- .env.*.local
37
-
38
- # IDE
39
- .vscode
40
- .idea
41
- *.swp
42
- *.swo
43
- *~
44
-
45
- # OS
46
- .DS_Store
47
- Thumbs.db
48
-
49
- # Templates (do not format generated/scaffold content)
50
- templates
51
- **/templates/**
52
- *.hbs
1
+ # Dependencies
2
+ node_modules
3
+ **/node_modules
4
+
5
+ # Build outputs
6
+ .next
7
+ out
8
+ dist
9
+ build
10
+ **/dist
11
+ **/.next
12
+ **/out
13
+ **/build
14
+
15
+ # Generated files
16
+ *.min.js
17
+ *.min.css
18
+ coverage
19
+ .nyc_output
20
+
21
+ # Lock files
22
+ package-lock.json
23
+ yarn.lock
24
+ pnpm-lock.yaml
25
+ bun.lock
26
+
27
+ # Logs
28
+ *.log
29
+ npm-debug.log*
30
+ yarn-debug.log*
31
+ yarn-error.log*
32
+
33
+ # Environment files
34
+ .env
35
+ .env.local
36
+ .env.*.local
37
+
38
+ # IDE
39
+ .vscode
40
+ .idea
41
+ *.swp
42
+ *.swo
43
+ *~
44
+
45
+ # OS
46
+ .DS_Store
47
+ Thumbs.db
48
+
49
+ # Templates (do not format generated/scaffold content)
50
+ templates
51
+ **/templates/**
52
+ *.hbs
@@ -13,28 +13,28 @@
13
13
  "type:check": "tsc --noEmit"
14
14
  },
15
15
  "dependencies": {
16
- "@nestjs/common": "^12.1.2",
17
- "@nestjs/core": "^12.1.2",
18
- "@nestjs/platform-express": "^12.1.2",
16
+ "@nestjs/common": "^12.3.2",
17
+ "@nestjs/core": "^12.3.2",
18
+ "@nestjs/platform-express": "^12.3.2",
19
19
  "cross-env": "^10.1.0",
20
20
  "dotenv": "^17.4.2",
21
21
  "helmet": "^8.3.0",
22
22
  "reflect-metadata": "^0.2.2",
23
23
  "rxjs": "^7.8.2",
24
- "zod": "^4.6.5"
24
+ "zod": "^4.6.7"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@eslint/js": "^10.0.1",
28
- "@nestjs/cli": "^12.0.8",
29
- "@nestjs/schematics": "^12.0.6",
28
+ "@nestjs/cli": "^12.0.11",
29
+ "@nestjs/schematics": "^12.0.12",
30
30
  "@trivago/prettier-plugin-sort-imports": "^6.0.2",
31
31
  "@types/express": "^5.0.6",
32
- "@types/node": "^24.13.3",
33
- "eslint": "^10.10.0",
32
+ "@types/node": "^24.19.2",
33
+ "eslint": "^10.14.0",
34
34
  "eslint-config-prettier": "^10.1.8",
35
- "prettier": "^3.9.6",
35
+ "prettier": "^3.9.10",
36
36
  "typescript": "^6.0.3",
37
- "typescript-eslint": "^8.69.0"
37
+ "typescript-eslint": "^8.72.1"
38
38
  },
39
39
  "envVars": {
40
40
  "PORT": "3000",
@@ -18,7 +18,9 @@ yarn-debug.log*
18
18
  yarn-error.log*
19
19
 
20
20
  # IDE
21
- .vscode/
21
+ .vscode/*
22
+ !.vscode/settings.json
23
+ !.vscode/extensions.json
22
24
  .idea/
23
25
  *.swp
24
26
  *.swo
@@ -34,3 +36,6 @@ coverage/
34
36
 
35
37
  # Misc
36
38
  *.tsbuildinfo
39
+
40
+ # Prisma client, created by prisma generate
41
+ src/generated/
@@ -35,7 +35,7 @@ import { PrismaModule } from "./prisma/prisma.module.js";
35
35
  AuthModule,
36
36
  {{/if}}
37
37
  {{#if useRateLimit}}
38
- // Every route: 100 requests per client IP in 15 minutes
38
+ // Every route except /health: 100 requests per client IP in 15 minutes
39
39
  ThrottlerModule.forRoot([{ ttl: 15 * 60 * 1000, limit: 100 }]),
40
40
  {{/if}}
41
41
  ],
@@ -1,5 +1,13 @@
1
1
  import { Controller, Get } from "@nestjs/common";
2
+ {{#if useRateLimit}}
3
+ import { SkipThrottle } from "@nestjs/throttler";
4
+ {{/if}}
2
5
 
6
+ {{#if useRateLimit}}
7
+ // Docker and load balancers call the health check on a schedule, so it is not
8
+ // counted
9
+ @SkipThrottle()
10
+ {{/if}}
3
11
  @Controller("health")
4
12
  export class HealthController {
5
13
  @Get()
@@ -1,9 +1,9 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "compilerOptions": {
4
- "noEmit": true,
5
- "allowJs": true,
6
- "rootDir": "."
7
- },
8
- "include": ["src/**/*", "eslint.config.mjs", "prisma.config.ts"]
9
- }
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "compilerOptions": {
4
+ "noEmit": true,
5
+ "allowJs": true,
6
+ "rootDir": "."
7
+ },
8
+ "include": ["src/**/*", "eslint.config.mjs", "prisma.config.ts"]
9
+ }
@@ -1,89 +1,89 @@
1
- @import "tailwindcss";
2
-
3
- :root {
4
- --radius: 0.65rem;
5
- --background: oklch(1 0 0);
6
- --foreground: oklch(0.145 0 0);
7
- --card: oklch(1 0 0);
8
- --card-foreground: oklch(0.145 0 0);
9
- --popover: oklch(1 0 0);
10
- --popover-foreground: oklch(0.145 0 0);
11
- --primary: oklch(0.205 0 0);
12
- --primary-foreground: oklch(0.985 0 0);
13
- --secondary: oklch(0.97 0 0);
14
- --secondary-foreground: oklch(0.205 0 0);
15
- --muted: oklch(0.97 0 0);
16
- --muted-foreground: oklch(0.556 0 0);
17
- --accent: oklch(0.97 0 0);
18
- --accent-foreground: oklch(0.205 0 0);
19
- --destructive: oklch(0.577 0.245 27.325);
20
- --border: oklch(0.922 0 0);
21
- --input: oklch(0.922 0 0);
22
- --ring: oklch(0.708 0 0);
23
- --chart-1: oklch(0.646 0.222 41.116);
24
- --chart-2: oklch(0.6 0.118 184.704);
25
- --chart-3: oklch(0.398 0.07 227.392);
26
- --chart-4: oklch(0.828 0.189 84.429);
27
- --chart-5: oklch(0.769 0.188 70.08);
28
- --radius: 0.625rem;
29
- --sidebar: oklch(0.985 0 0);
30
- --sidebar-foreground: oklch(0.145 0 0);
31
- --sidebar-primary: oklch(0.205 0 0);
32
- --sidebar-primary-foreground: oklch(0.985 0 0);
33
- --sidebar-accent: oklch(0.97 0 0);
34
- --sidebar-accent-foreground: oklch(0.205 0 0);
35
- --sidebar-border: oklch(0.922 0 0);
36
- --sidebar-ring: oklch(0.708 0 0);
37
- }
38
-
39
- .dark {
40
- --background: oklch(0.145 0 0);
41
- --foreground: oklch(0.985 0 0);
42
- --card: oklch(0.205 0 0);
43
- --card-foreground: oklch(0.985 0 0);
44
- --popover: oklch(0.205 0 0);
45
- --popover-foreground: oklch(0.985 0 0);
46
- --primary: oklch(0.922 0 0);
47
- --primary-foreground: oklch(0.205 0 0);
48
- --secondary: oklch(0.269 0 0);
49
- --secondary-foreground: oklch(0.985 0 0);
50
- --muted: oklch(0.269 0 0);
51
- --muted-foreground: oklch(0.708 0 0);
52
- --accent: oklch(0.269 0 0);
53
- --accent-foreground: oklch(0.985 0 0);
54
- --destructive: oklch(0.704 0.191 22.216);
55
- --border: oklch(1 0 0 / 10%);
56
- --input: oklch(1 0 0 / 15%);
57
- --ring: oklch(0.556 0 0);
58
- --chart-1: oklch(0.488 0.243 264.376);
59
- --chart-2: oklch(0.696 0.17 162.48);
60
- --chart-3: oklch(0.769 0.188 70.08);
61
- --chart-4: oklch(0.627 0.265 303.9);
62
- --chart-5: oklch(0.645 0.246 16.439);
63
- --sidebar: oklch(0.205 0 0);
64
- --sidebar-foreground: oklch(0.985 0 0);
65
- --sidebar-primary: oklch(0.488 0.243 264.376);
66
- --sidebar-primary-foreground: oklch(0.985 0 0);
67
- --sidebar-accent: oklch(0.269 0 0);
68
- --sidebar-accent-foreground: oklch(0.985 0 0);
69
- --sidebar-border: oklch(1 0 0 / 10%);
70
- --sidebar-ring: oklch(0.556 0 0);
71
- }
72
- * {
73
- border-color: var(--border);
74
- }
75
-
76
- body {
77
- background: var(--background);
78
- color: var(--foreground);
79
- font-family: var(--font-geist-sans), sans-serif;
80
- }
81
-
82
- a {
83
- text-underline-offset: 0.2rem;
84
- }
85
-
86
- ::selection {
87
- background: color-mix(in oklab, var(--accent) 65%, white);
88
- color: var(--foreground);
89
- }
1
+ @import "tailwindcss";
2
+
3
+ :root {
4
+ --radius: 0.65rem;
5
+ --background: oklch(1 0 0);
6
+ --foreground: oklch(0.145 0 0);
7
+ --card: oklch(1 0 0);
8
+ --card-foreground: oklch(0.145 0 0);
9
+ --popover: oklch(1 0 0);
10
+ --popover-foreground: oklch(0.145 0 0);
11
+ --primary: oklch(0.205 0 0);
12
+ --primary-foreground: oklch(0.985 0 0);
13
+ --secondary: oklch(0.97 0 0);
14
+ --secondary-foreground: oklch(0.205 0 0);
15
+ --muted: oklch(0.97 0 0);
16
+ --muted-foreground: oklch(0.556 0 0);
17
+ --accent: oklch(0.97 0 0);
18
+ --accent-foreground: oklch(0.205 0 0);
19
+ --destructive: oklch(0.577 0.245 27.325);
20
+ --border: oklch(0.922 0 0);
21
+ --input: oklch(0.922 0 0);
22
+ --ring: oklch(0.708 0 0);
23
+ --chart-1: oklch(0.646 0.222 41.116);
24
+ --chart-2: oklch(0.6 0.118 184.704);
25
+ --chart-3: oklch(0.398 0.07 227.392);
26
+ --chart-4: oklch(0.828 0.189 84.429);
27
+ --chart-5: oklch(0.769 0.188 70.08);
28
+ --radius: 0.625rem;
29
+ --sidebar: oklch(0.985 0 0);
30
+ --sidebar-foreground: oklch(0.145 0 0);
31
+ --sidebar-primary: oklch(0.205 0 0);
32
+ --sidebar-primary-foreground: oklch(0.985 0 0);
33
+ --sidebar-accent: oklch(0.97 0 0);
34
+ --sidebar-accent-foreground: oklch(0.205 0 0);
35
+ --sidebar-border: oklch(0.922 0 0);
36
+ --sidebar-ring: oklch(0.708 0 0);
37
+ }
38
+
39
+ .dark {
40
+ --background: oklch(0.145 0 0);
41
+ --foreground: oklch(0.985 0 0);
42
+ --card: oklch(0.205 0 0);
43
+ --card-foreground: oklch(0.985 0 0);
44
+ --popover: oklch(0.205 0 0);
45
+ --popover-foreground: oklch(0.985 0 0);
46
+ --primary: oklch(0.922 0 0);
47
+ --primary-foreground: oklch(0.205 0 0);
48
+ --secondary: oklch(0.269 0 0);
49
+ --secondary-foreground: oklch(0.985 0 0);
50
+ --muted: oklch(0.269 0 0);
51
+ --muted-foreground: oklch(0.708 0 0);
52
+ --accent: oklch(0.269 0 0);
53
+ --accent-foreground: oklch(0.985 0 0);
54
+ --destructive: oklch(0.704 0.191 22.216);
55
+ --border: oklch(1 0 0 / 10%);
56
+ --input: oklch(1 0 0 / 15%);
57
+ --ring: oklch(0.556 0 0);
58
+ --chart-1: oklch(0.488 0.243 264.376);
59
+ --chart-2: oklch(0.696 0.17 162.48);
60
+ --chart-3: oklch(0.769 0.188 70.08);
61
+ --chart-4: oklch(0.627 0.265 303.9);
62
+ --chart-5: oklch(0.645 0.246 16.439);
63
+ --sidebar: oklch(0.205 0 0);
64
+ --sidebar-foreground: oklch(0.985 0 0);
65
+ --sidebar-primary: oklch(0.488 0.243 264.376);
66
+ --sidebar-primary-foreground: oklch(0.985 0 0);
67
+ --sidebar-accent: oklch(0.269 0 0);
68
+ --sidebar-accent-foreground: oklch(0.985 0 0);
69
+ --sidebar-border: oklch(1 0 0 / 10%);
70
+ --sidebar-ring: oklch(0.556 0 0);
71
+ }
72
+ * {
73
+ border-color: var(--border);
74
+ }
75
+
76
+ body {
77
+ background: var(--background);
78
+ color: var(--foreground);
79
+ font-family: var(--font-geist-sans), sans-serif;
80
+ }
81
+
82
+ a {
83
+ text-underline-offset: 0.2rem;
84
+ }
85
+
86
+ ::selection {
87
+ background: color-mix(in oklab, var(--accent) 65%, white);
88
+ color: var(--foreground);
89
+ }
@@ -1,34 +1,34 @@
1
- import type { Metadata } from "next";
2
- import { Geist, Geist_Mono } from "next/font/google";
3
- import "./globals.css";
4
-
5
- const geistSans = Geist({
6
- variable: "--font-geist-sans",
7
- subsets: ["latin"],
8
- });
9
-
10
- const geistMono = Geist_Mono({
11
- variable: "--font-geist-mono",
12
- subsets: ["latin"],
13
- });
14
-
15
- export const metadata: Metadata = {
16
- title: "better-ts-stack starter",
17
- description: "Generated with better-ts-stack",
18
- };
19
-
20
- export default function RootLayout({
21
- children,
22
- }: Readonly<{
23
- children: React.ReactNode;
24
- }>) {
25
- return (
26
- <html lang="en">
27
- <body
28
- className={`${geistSans.variable} ${geistMono.variable} bg-background text-foreground antialiased`}
29
- >
30
- {children}
31
- </body>
32
- </html>
33
- );
34
- }
1
+ import type { Metadata } from "next";
2
+ import { Geist, Geist_Mono } from "next/font/google";
3
+ import "./globals.css";
4
+
5
+ const geistSans = Geist({
6
+ variable: "--font-geist-sans",
7
+ subsets: ["latin"],
8
+ });
9
+
10
+ const geistMono = Geist_Mono({
11
+ variable: "--font-geist-mono",
12
+ subsets: ["latin"],
13
+ });
14
+
15
+ export const metadata: Metadata = {
16
+ title: "better-ts-stack starter",
17
+ description: "Generated with better-ts-stack",
18
+ };
19
+
20
+ export default function RootLayout({
21
+ children,
22
+ }: Readonly<{
23
+ children: React.ReactNode;
24
+ }>) {
25
+ return (
26
+ <html lang="en">
27
+ <body
28
+ className={`${geistSans.variable} ${geistMono.variable} bg-background text-foreground antialiased`}
29
+ >
30
+ {children}
31
+ </body>
32
+ </html>
33
+ );
34
+ }
@@ -1,51 +1,51 @@
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 buttonVariants = cva(
7
- "inline-flex items-center justify-center whitespace-nowrap rounded-full text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:pointer-events-none disabled:opacity-50",
8
- {
9
- variants: {
10
- variant: {
11
- default:
12
- "bg-slate-950 text-white shadow-sm hover:bg-slate-800",
13
- outline:
14
- "border border-slate-200 bg-white text-slate-900 hover:bg-slate-100",
15
- ghost: "text-slate-700 hover:bg-slate-100 hover:text-slate-950",
16
- },
17
- size: {
18
- default: "h-10 px-4 py-2",
19
- sm: "h-9 px-3",
20
- lg: "h-11 px-6 text-sm",
21
- icon: "size-10",
22
- },
23
- },
24
- defaultVariants: {
25
- variant: "default",
26
- size: "default",
27
- },
28
- }
29
- );
30
-
31
- export interface ButtonProps
32
- extends React.ButtonHTMLAttributes<HTMLButtonElement>,
33
- VariantProps<typeof buttonVariants> {}
34
-
35
- function Button({
36
- className,
37
- variant,
38
- size,
39
- type = "button",
40
- ...props
41
- }: ButtonProps) {
42
- return (
43
- <button
44
- type={type}
45
- className={cn(buttonVariants({ variant, size }), className)}
46
- {...props}
47
- />
48
- );
49
- }
50
-
51
- export { Button, buttonVariants };
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 buttonVariants = cva(
7
+ "inline-flex items-center justify-center whitespace-nowrap rounded-full text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-500 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:pointer-events-none disabled:opacity-50",
8
+ {
9
+ variants: {
10
+ variant: {
11
+ default:
12
+ "bg-slate-950 text-white shadow-sm hover:bg-slate-800",
13
+ outline:
14
+ "border border-slate-200 bg-white text-slate-900 hover:bg-slate-100",
15
+ ghost: "text-slate-700 hover:bg-slate-100 hover:text-slate-950",
16
+ },
17
+ size: {
18
+ default: "h-10 px-4 py-2",
19
+ sm: "h-9 px-3",
20
+ lg: "h-11 px-6 text-sm",
21
+ icon: "size-10",
22
+ },
23
+ },
24
+ defaultVariants: {
25
+ variant: "default",
26
+ size: "default",
27
+ },
28
+ }
29
+ );
30
+
31
+ export interface ButtonProps
32
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
33
+ VariantProps<typeof buttonVariants> {}
34
+
35
+ function Button({
36
+ className,
37
+ variant,
38
+ size,
39
+ type = "button",
40
+ ...props
41
+ }: ButtonProps) {
42
+ return (
43
+ <button
44
+ type={type}
45
+ className={cn(buttonVariants({ variant, size }), className)}
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+
51
+ export { Button, buttonVariants };
@@ -1,60 +1,60 @@
1
- import * as React from "react";
2
-
3
- import { cn } from "@/lib/utils";
4
-
5
- function Card({
6
- className,
7
- ...props
8
- }: React.HTMLAttributes<HTMLDivElement>) {
9
- return (
10
- <div
11
- className={cn(
12
- "rounded-3xl border border-slate-200/80 bg-white text-slate-950 shadow-sm",
13
- className
14
- )}
15
- {...props}
16
- />
17
- );
18
- }
19
-
20
- function CardHeader({
21
- className,
22
- ...props
23
- }: React.HTMLAttributes<HTMLDivElement>) {
24
- return <div className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />;
25
- }
26
-
27
- function CardTitle({
28
- className,
29
- ...props
30
- }: React.HTMLAttributes<HTMLHeadingElement>) {
31
- return (
32
- <h3
33
- className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
34
- {...props}
35
- />
36
- );
37
- }
38
-
39
- function CardDescription({
40
- className,
41
- ...props
42
- }: React.HTMLAttributes<HTMLParagraphElement>) {
43
- return <p className={cn("text-sm text-slate-600", className)} {...props} />;
44
- }
45
-
46
- function CardContent({
47
- className,
48
- ...props
49
- }: React.HTMLAttributes<HTMLDivElement>) {
50
- return <div className={cn("p-6 pt-0", className)} {...props} />;
51
- }
52
-
53
- function CardFooter({
54
- className,
55
- ...props
56
- }: React.HTMLAttributes<HTMLDivElement>) {
57
- return <div className={cn("flex items-center p-6 pt-0", className)} {...props} />;
58
- }
59
-
60
- export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
1
+ import * as React from "react";
2
+
3
+ import { cn } from "@/lib/utils";
4
+
5
+ function Card({
6
+ className,
7
+ ...props
8
+ }: React.HTMLAttributes<HTMLDivElement>) {
9
+ return (
10
+ <div
11
+ className={cn(
12
+ "rounded-3xl border border-slate-200/80 bg-white text-slate-950 shadow-sm",
13
+ className
14
+ )}
15
+ {...props}
16
+ />
17
+ );
18
+ }
19
+
20
+ function CardHeader({
21
+ className,
22
+ ...props
23
+ }: React.HTMLAttributes<HTMLDivElement>) {
24
+ return <div className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />;
25
+ }
26
+
27
+ function CardTitle({
28
+ className,
29
+ ...props
30
+ }: React.HTMLAttributes<HTMLHeadingElement>) {
31
+ return (
32
+ <h3
33
+ className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
34
+ {...props}
35
+ />
36
+ );
37
+ }
38
+
39
+ function CardDescription({
40
+ className,
41
+ ...props
42
+ }: React.HTMLAttributes<HTMLParagraphElement>) {
43
+ return <p className={cn("text-sm text-slate-600", className)} {...props} />;
44
+ }
45
+
46
+ function CardContent({
47
+ className,
48
+ ...props
49
+ }: React.HTMLAttributes<HTMLDivElement>) {
50
+ return <div className={cn("p-6 pt-0", className)} {...props} />;
51
+ }
52
+
53
+ function CardFooter({
54
+ className,
55
+ ...props
56
+ }: React.HTMLAttributes<HTMLDivElement>) {
57
+ return <div className={cn("flex items-center p-6 pt-0", className)} {...props} />;
58
+ }
59
+
60
+ export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };