Skip to content

Commit 2da75fb

Browse files
committed
feat(ui): add initial UI package with Button and Input components
- Created a new UI package with essential components including Button and Input. - Integrated Tailwind CSS for styling and utility classes. - Added utility functions for class name management. - Configured TypeScript and PostCSS for the UI package. - Updated server authentication to use dynamic import for better performance.
1 parent 4ba611d commit 2da75fb

File tree

13 files changed

+1617
-22
lines changed

13 files changed

+1617
-22
lines changed

package-lock.json

Lines changed: 1390 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/server/src/auth/auth.client.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
1-
import { betterAuth } from "better-auth";
1+
import { Pool } from "pg";
2+
3+
let authInstance: any;
4+
5+
export const getAuth = async () => {
6+
if (authInstance) return authInstance;
7+
const { betterAuth } = await import("better-auth");
8+
9+
authInstance = betterAuth({
10+
database: {
11+
provider: "postgres",
12+
pool: new Pool({
13+
connectionString: process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/objectql'
14+
})
15+
},
16+
emailAndPassword: {
17+
enabled: true
18+
}
19+
});
20+
return authInstance;
21+
};
222

3-
export const auth = betterAuth({
4-
database: {
5-
provider: "postgres",
6-
url: process.env.DATABASE_URL || 'postgres://postgres:postgres@localhost:5432/objectql'
7-
},
8-
emailAndPassword: {
9-
enabled: true
10-
}
11-
});
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Controller, All, Req, Res } from '@nestjs/common';
2-
import { auth } from './auth.client';
3-
import { toNodeHandler } from 'better-auth/node';
2+
import { getAuth } from './auth.client';
43

54
@Controller('api/auth')
65
export class AuthController {
76
@All('*')
87
async handleAuth(@Req() req, @Res() res) {
8+
const auth = await getAuth();
9+
const { toNodeHandler } = await import('better-auth/node');
910
return toNodeHandler(auth)(req, res);
1011
}
1112
}

packages/ui/package.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "@objectql/ui",
3+
"version": "0.1.0",
4+
"private": false,
5+
"main": "dist/index.js",
6+
"module": "dist/index.mjs",
7+
"types": "dist/index.d.ts",
8+
"files": [
9+
"dist"
10+
],
11+
"scripts": {
12+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
13+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
14+
"lint": "eslint src/**",
15+
"test": "echo \"No tests specified\" && exit 0"
16+
},
17+
"peerDependencies": {
18+
"react": ">=18",
19+
"react-dom": ">=18"
20+
},
21+
"devDependencies": {
22+
"@types/react": "^18.2.0",
23+
"@types/react-dom": "^18.2.0",
24+
"autoprefixer": "^10.4.0",
25+
"postcss": "^8.4.0",
26+
"react": "^18.2.0",
27+
"react-dom": "^18.2.0",
28+
"tailwindcss": "^3.4.0",
29+
"tsup": "^8.0.0",
30+
"typescript": "^5.0.0"
31+
},
32+
"dependencies": {
33+
"@radix-ui/react-slot": "^1.2.4",
34+
"class-variance-authority": "^0.7.1",
35+
"clsx": "^2.1.1",
36+
"lucide-react": "^0.562.0",
37+
"tailwind-merge": "^3.4.0"
38+
}
39+
}

packages/ui/postcss.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import * as React from "react"
2+
import { Slot } from "@radix-ui/react-slot"
3+
import { cva, type VariantProps } from "class-variance-authority"
4+
5+
import { cn } from "../lib/utils"
6+
7+
const buttonVariants = cva(
8+
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
9+
{
10+
variants: {
11+
variant: {
12+
default: "bg-stone-900 text-stone-50 hover:bg-stone-900/90",
13+
destructive:
14+
"bg-red-500 text-stone-50 hover:bg-red-500/90",
15+
outline:
16+
"border border-stone-200 bg-white hover:bg-stone-100 hover:text-stone-900",
17+
secondary:
18+
"bg-stone-100 text-stone-900 hover:bg-stone-100/80",
19+
ghost: "hover:bg-stone-100 hover:text-stone-900",
20+
link: "text-stone-900 underline-offset-4 hover:underline",
21+
},
22+
size: {
23+
default: "h-10 px-4 py-2",
24+
sm: "h-9 rounded-md px-3",
25+
lg: "h-11 rounded-md px-8",
26+
icon: "h-10 w-10",
27+
},
28+
},
29+
defaultVariants: {
30+
variant: "default",
31+
size: "default",
32+
},
33+
}
34+
)
35+
36+
export interface ButtonProps
37+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
38+
VariantProps<typeof buttonVariants> {
39+
asChild?: boolean
40+
}
41+
42+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
43+
({ className, variant, size, asChild = false, ...props }, ref) => {
44+
const Comp = asChild ? Slot : "button"
45+
return (
46+
<Comp
47+
className={cn(buttonVariants({ variant, size, className }))}
48+
ref={ref}
49+
{...props}
50+
/>
51+
)
52+
}
53+
)
54+
Button.displayName = "Button"
55+
56+
export { Button, buttonVariants }
57+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as React from "react"
2+
import { cn } from "../lib/utils"
3+
4+
export interface InputProps
5+
extends React.InputHTMLAttributes<HTMLInputElement> {}
6+
7+
const Input = React.forwardRef<HTMLInputElement, InputProps>(
8+
({ className, type, ...props }, ref) => {
9+
return (
10+
<input
11+
type={type}
12+
className={cn(
13+
"flex h-10 w-full rounded-md border border-stone-200 bg-white px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-stone-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-stone-950 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
14+
className
15+
)}
16+
ref={ref}
17+
{...props}
18+
/>
19+
)
20+
}
21+
)
22+
Input.displayName = "Input"
23+
24+
export { Input }

packages/ui/src/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import './styles.css';
2+
export * from './lib/utils';
3+
export * from './components/Button';
4+
export * from './components/Input';

packages/ui/src/lib/utils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { type ClassValue, clsx } from "clsx"
2+
import { twMerge } from "tailwind-merge"
3+
4+
export function cn(...inputs: ClassValue[]) {
5+
return twMerge(clsx(inputs))
6+
}

packages/ui/src/styles.css

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
@layer base {
6+
:root {
7+
--background: 0 0% 100%;
8+
--foreground: 20 14.3% 4.1%;
9+
10+
--card: 0 0% 100%;
11+
--card-foreground: 20 14.3% 4.1%;
12+
13+
--popover: 0 0% 100%;
14+
--popover-foreground: 20 14.3% 4.1%;
15+
16+
--primary: 24 9.8% 10%;
17+
--primary-foreground: 60 9.1% 97.8%;
18+
19+
--secondary: 60 4.8% 95.9%;
20+
--secondary-foreground: 24 9.8% 10%;
21+
22+
--muted: 60 4.8% 95.9%;
23+
--muted-foreground: 25 5.3% 44.7%;
24+
25+
--accent: 60 4.8% 95.9%;
26+
--accent-foreground: 24 9.8% 10%;
27+
28+
--destructive: 0 84.2% 60.2%;
29+
--destructive-foreground: 60 9.1% 97.8%;
30+
31+
--border: 20 5.9% 90%;
32+
--input: 20 5.9% 90%;
33+
--ring: 20 14.3% 4.1%;
34+
35+
--radius: 0.5rem;
36+
}
37+
}
38+
39+
@layer base {
40+
* {
41+
@apply border-stone-200;
42+
}
43+
body {
44+
@apply bg-white text-stone-950;
45+
}
46+
}

0 commit comments

Comments
 (0)