diff --git a/apps/next-template/components.json b/apps/next-template/components.json
new file mode 100644
index 0000000..83dc8b6
--- /dev/null
+++ b/apps/next-template/components.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": true,
+ "tsx": true,
+ "tailwind": {
+ "config": "",
+ "css": "../../packages/ui/src/styles/globals.css",
+ "baseColor": "neutral",
+ "cssVariables": true
+ },
+ "iconLibrary": "lucide",
+ "aliases": {
+ "components": "@/components",
+ "hooks": "@/hooks",
+ "lib": "@/lib",
+ "utils": "@repo/ui/lib/utils",
+ "ui": "@repo/ui/components"
+ }
+}
diff --git a/apps/next-template/next.config.ts b/apps/next-template/next.config.ts
index 3a30715..e24e368 100644
--- a/apps/next-template/next.config.ts
+++ b/apps/next-template/next.config.ts
@@ -1,12 +1,13 @@
import { NextConfig } from "next";
const nextConfig: NextConfig = {
- typescript: {
- ignoreBuildErrors: true,
- },
- eslint: {
- ignoreDuringBuilds: true,
- },
+ typescript: {
+ ignoreBuildErrors: true,
+ },
+ eslint: {
+ ignoreDuringBuilds: true,
+ },
+ transpilePackages: ["@repo/ui"],
};
export default nextConfig;
diff --git a/apps/next-template/src/app/layout.tsx b/apps/next-template/src/app/layout.tsx
index 0fa9cdd..ac4f087 100644
--- a/apps/next-template/src/app/layout.tsx
+++ b/apps/next-template/src/app/layout.tsx
@@ -1,5 +1,5 @@
import "@repo/ui/styles/styles.css";
-import "@repo/ui/globals.css";
+import "@repo/ui/styles/global.css";
export default function RootLayout({
children,
diff --git a/apps/next-template/src/app/shadcn/page.tsx b/apps/next-template/src/app/shadcn/page.tsx
index 78e6224..7589d73 100644
--- a/apps/next-template/src/app/shadcn/page.tsx
+++ b/apps/next-template/src/app/shadcn/page.tsx
@@ -1,10 +1,10 @@
-import { Button } from "@repo/ui/components/button.js";
+import { Button } from "@repo/ui/components/button";
import {
Card,
CardContent,
CardHeader,
CardTitle,
-} from "@repo/ui/components/card.js";
+} from "@repo/ui/components/card";
export default function HomePage() {
return (
diff --git a/apps/next-template/tsconfig.json b/apps/next-template/tsconfig.json
index d87d332..abe79fe 100644
--- a/apps/next-template/tsconfig.json
+++ b/apps/next-template/tsconfig.json
@@ -1,13 +1,17 @@
{
- "exclude": ["node_modules"],
- "extends": "@repo/typescript-config/nextjs.json",
- "compilerOptions": {
- "outDir": "dist",
- "plugins": [
- {
- "name": "next"
- }
- ]
- },
- "include": ["src", "next.config.ts", "next-env.d.ts", ".next/types/**/*.ts"]
+ "exclude": ["node_modules"],
+ "extends": "@repo/typescript-config/nextjs.json",
+ "compilerOptions": {
+ "outDir": "dist",
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "~/*": ["./src/*"],
+ "@repo/ui/*": ["../../packages/ui/src/*"]
+ }
+ },
+ "include": ["src", "next.config.ts", "next-env.d.ts", ".next/types/**/*.ts"]
}
diff --git a/apps/remix-template/app/root.tsx b/apps/remix-template/app/root.tsx
index 6145eef..5fc8e46 100644
--- a/apps/remix-template/app/root.tsx
+++ b/apps/remix-template/app/root.tsx
@@ -7,7 +7,7 @@ import {
} from "@remix-run/react";
import { Analytics } from "@vercel/analytics/react";
import "@repo/ui/styles/styles.css";
-import "@repo/ui/globals.css";
+import "@repo/ui/styles/global.css";
export function Layout({ children }: { children: React.ReactNode }) {
return (
diff --git a/apps/remix-template/app/routes/_index.tsx b/apps/remix-template/app/routes/_index.tsx
index 1a4a993..f375240 100644
--- a/apps/remix-template/app/routes/_index.tsx
+++ b/apps/remix-template/app/routes/_index.tsx
@@ -1,5 +1,5 @@
-import { CounterButton } from "@repo/ui/counter-button/index.mjs";
-import { Link } from "@repo/ui/link/index.mjs";
+import { CounterButton } from "@repo/ui/counter-button";
+import { Link } from "@repo/ui/link";
export default function Index() {
return (
diff --git a/apps/remix-template/app/routes/shadcn.tsx b/apps/remix-template/app/routes/shadcn.tsx
index 20a19a1..92d4b44 100644
--- a/apps/remix-template/app/routes/shadcn.tsx
+++ b/apps/remix-template/app/routes/shadcn.tsx
@@ -1,11 +1,11 @@
-import { Button } from "@repo/ui/components/button.mjs";
+import { Button } from "@repo/ui/components/button";
import {
Card,
CardContent,
CardHeader,
CardTitle,
-} from "@repo/ui/components/card.mjs";
-import { Link } from "@repo/ui/link/index.mjs";
+} from "@repo/ui/components/card";
+import { Link } from "@repo/ui/link";
export default function Index() {
return (
diff --git a/apps/remix-template/package.json b/apps/remix-template/package.json
index 1188490..ff13669 100644
--- a/apps/remix-template/package.json
+++ b/apps/remix-template/package.json
@@ -11,6 +11,7 @@
"lint": "eslint app/ --max-warnings 0"
},
"dependencies": {
+ "@radix-ui/react-slot": "^1.2.3",
"@remix-run/node": "^2.15.2",
"@remix-run/react": "^2.15.2",
"@remix-run/server-runtime": "^2.15.2",
diff --git a/apps/remix-template/tsconfig.json b/apps/remix-template/tsconfig.json
index cb59c5d..15cd766 100644
--- a/apps/remix-template/tsconfig.json
+++ b/apps/remix-template/tsconfig.json
@@ -6,7 +6,8 @@
"module": "ESNext",
"skipLibCheck": true,
"paths": {
- "~/*": ["./app/*"]
+ "~/*": ["./app/*"],
+ "@repo/ui/*": ["../../packages/ui/src/*"]
},
// Vite takes care of building everything, not tsc.
diff --git a/apps/vite-template/components.json b/apps/vite-template/components.json
new file mode 100644
index 0000000..83dc8b6
--- /dev/null
+++ b/apps/vite-template/components.json
@@ -0,0 +1,20 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": true,
+ "tsx": true,
+ "tailwind": {
+ "config": "",
+ "css": "../../packages/ui/src/styles/globals.css",
+ "baseColor": "neutral",
+ "cssVariables": true
+ },
+ "iconLibrary": "lucide",
+ "aliases": {
+ "components": "@/components",
+ "hooks": "@/hooks",
+ "lib": "@/lib",
+ "utils": "@repo/ui/lib/utils",
+ "ui": "@repo/ui/components"
+ }
+}
diff --git a/apps/vite-template/package.json b/apps/vite-template/package.json
index 791f3ee..c039e03 100644
--- a/apps/vite-template/package.json
+++ b/apps/vite-template/package.json
@@ -22,6 +22,7 @@
"@vitejs/plugin-react": "^4.5.1",
"eslint": "^9.29.0",
"typescript": "5.8.2",
- "vite": "^5.4.14"
+ "vite": "^5.4.14",
+ "vite-tsconfig-paths": "^4.2.1"
}
}
diff --git a/apps/vite-template/postcss.config.mjs b/apps/vite-template/postcss.config.mjs
new file mode 100644
index 0000000..039248f
--- /dev/null
+++ b/apps/vite-template/postcss.config.mjs
@@ -0,0 +1 @@
+export { default } from "@repo/ui/postcss.config";
diff --git a/apps/vite-template/src/app/index.tsx b/apps/vite-template/src/app/index.tsx
index 6659320..70d0076 100644
--- a/apps/vite-template/src/app/index.tsx
+++ b/apps/vite-template/src/app/index.tsx
@@ -1,27 +1,44 @@
-import "./styles.css";
+import "@repo/ui/styles/styles.css";
+import "@repo/ui/styles/global.css";
import { CounterButton } from "@repo/ui/counter-button";
import { Link } from "@repo/ui/link";
+import { Button } from "@repo/ui/components/button";
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ CardTitle,
+} from "@repo/ui/components/card";
+
function App() {
- return (
-
-
- Admin
- Kitchen Sink
-
-
-
- Built With{" "}
-
- Turborepo
-
- {" & "}
-
- Vite
-
-
-
- );
+ return (
+
+
+ Admin
+ Kitchen Sink
+
+
+
+
+ shadcn/ui Card Example
+
+
+
+
+
+
+ Built With{" "}
+
+ Turborepo
+
+ {" & "}
+
+ Vite
+
+
+
+ );
}
export default App;
diff --git a/apps/vite-template/src/app/styles.css b/apps/vite-template/src/app/styles.css
deleted file mode 100644
index dc5bbf4..0000000
--- a/apps/vite-template/src/app/styles.css
+++ /dev/null
@@ -1,40 +0,0 @@
-.container {
- min-height: 100vh;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 1.5rem;
- max-width: 100%;
- margin: 0 auto;
- padding: 0 16px;
- text-align: center;
-}
-
-.title {
- font-size: 3rem;
- font-weight: 700;
- margin: 0;
-}
-
-.title span {
- display: inline-block;
- background-image: linear-gradient(to right, #3b82f6, #ef4444);
- -webkit-background-clip: text;
- background-clip: text;
- color: transparent;
-}
-
-.description {
- color: #9ca3af;
- font-weight: 500;
-}
-
-.description a {
- color: #3b82f6;
- text-decoration: none;
-}
-
-.description a:hover {
- text-decoration: underline;
-}
diff --git a/apps/vite-template/tailwind.config.ts b/apps/vite-template/tailwind.config.ts
new file mode 100644
index 0000000..412b593
--- /dev/null
+++ b/apps/vite-template/tailwind.config.ts
@@ -0,0 +1 @@
+export { default } from "@repo/ui/tailwind.config";
diff --git a/apps/vite-template/tsconfig.json b/apps/vite-template/tsconfig.json
index a7fc6fb..93e4849 100644
--- a/apps/vite-template/tsconfig.json
+++ b/apps/vite-template/tsconfig.json
@@ -1,25 +1,29 @@
{
- "compilerOptions": {
- "target": "ES2020",
- "useDefineForClassFields": true,
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "module": "ESNext",
- "skipLibCheck": true,
+ "compilerOptions": {
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "paths": {
+ "~/*": ["./src/*"],
+ "@repo/ui/*": ["../../packages/ui/src/*"]
+ },
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx",
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["src"],
- "references": [{ "path": "./tsconfig.node.json" }]
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"],
+ "references": [{ "path": "./tsconfig.node.json" }]
}
diff --git a/apps/vite-template/vite.config.ts b/apps/vite-template/vite.config.ts
index 58676f7..975c787 100644
--- a/apps/vite-template/vite.config.ts
+++ b/apps/vite-template/vite.config.ts
@@ -1,6 +1,7 @@
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
+import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
- plugins: [react()],
+ plugins: [react(), tsconfigPaths()],
});
diff --git a/package-lock.json b/package-lock.json
index b15f2aa..cf44244 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -166,6 +166,7 @@
"apps/remix-template": {
"version": "0.0.0",
"dependencies": {
+ "@radix-ui/react-slot": "^1.2.3",
"@remix-run/node": "^2.15.2",
"@remix-run/react": "^2.15.2",
"@remix-run/server-runtime": "^2.15.2",
@@ -285,7 +286,8 @@
"@vitejs/plugin-react": "^4.5.1",
"eslint": "^9.29.0",
"typescript": "5.8.2",
- "vite": "^5.4.14"
+ "vite": "^5.4.14",
+ "vite-tsconfig-paths": "^4.2.1"
}
},
"apps/web": {
@@ -3212,6 +3214,57 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
+ "node_modules/@remix-run/express": {
+ "version": "2.16.8",
+ "resolved": "https://registry.npmjs.org/@remix-run/express/-/express-2.16.8.tgz",
+ "integrity": "sha512-NNTosiAJ4jZCRDfWSjV+3Fyu7KoHPeEHruLZEPRNDuXO6Nm5EkRvIkMwdfwyJ+ajE5IPotu8MFtPyNtm3sw/gw==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@remix-run/node": "2.16.8"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "express": "^4.20.0",
+ "typescript": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@remix-run/express/node_modules/@remix-run/node": {
+ "version": "2.16.8",
+ "resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.16.8.tgz",
+ "integrity": "sha512-foeYXU3mdaBJZnbtGbM8mNdHowz2+QnVGDRo7P3zgFkmsccMEflArGZNbkACGKd9xwDguTxxMJ6cuXBC4jIfgQ==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@remix-run/server-runtime": "2.16.8",
+ "@remix-run/web-fetch": "^4.4.2",
+ "@web3-storage/multipart-parser": "^1.0.0",
+ "cookie-signature": "^1.1.0",
+ "source-map-support": "^0.5.21",
+ "stream-slice": "^0.1.2",
+ "undici": "^6.21.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "typescript": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@remix-run/node": {
"version": "2.15.3",
"resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.15.3.tgz",
@@ -3314,6 +3367,58 @@
"node": ">=14.0.0"
}
},
+ "node_modules/@remix-run/serve": {
+ "version": "2.16.8",
+ "resolved": "https://registry.npmjs.org/@remix-run/serve/-/serve-2.16.8.tgz",
+ "integrity": "sha512-4exyeXCZoc/Vo8Zc+6Eyao3ONwOyNOK3Yeb0LLkWXd4aeFQ4v59i5fq/j/E+68UnpD/UZQl1Bj0k2hQnGQZhlQ==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@remix-run/express": "2.16.8",
+ "@remix-run/node": "2.16.8",
+ "chokidar": "^3.5.3",
+ "compression": "^1.7.4",
+ "express": "^4.20.0",
+ "get-port": "5.1.1",
+ "morgan": "^1.10.0",
+ "source-map-support": "^0.5.21"
+ },
+ "bin": {
+ "remix-serve": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@remix-run/serve/node_modules/@remix-run/node": {
+ "version": "2.16.8",
+ "resolved": "https://registry.npmjs.org/@remix-run/node/-/node-2.16.8.tgz",
+ "integrity": "sha512-foeYXU3mdaBJZnbtGbM8mNdHowz2+QnVGDRo7P3zgFkmsccMEflArGZNbkACGKd9xwDguTxxMJ6cuXBC4jIfgQ==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "@remix-run/server-runtime": "2.16.8",
+ "@remix-run/web-fetch": "^4.4.2",
+ "@web3-storage/multipart-parser": "^1.0.0",
+ "cookie-signature": "^1.1.0",
+ "source-map-support": "^0.5.21",
+ "stream-slice": "^0.1.2",
+ "undici": "^6.21.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "typescript": "^5.1.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@remix-run/server-runtime": {
"version": "2.16.8",
"resolved": "https://registry.npmjs.org/@remix-run/server-runtime/-/server-runtime-2.16.8.tgz",
@@ -6975,6 +7080,70 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "mime-db": ">= 1.43.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/compression": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz",
+ "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "bytes": "3.1.2",
+ "compressible": "~2.0.18",
+ "debug": "2.6.9",
+ "negotiator": "~0.6.4",
+ "on-headers": "~1.0.2",
+ "safe-buffer": "5.2.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/compression/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/compression/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true
+ },
+ "node_modules/compression/node_modules/negotiator": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+ "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 6cf5ea7..78825d3 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -43,7 +43,7 @@
"exports": {
"./postcss.config": "./postcss.config.mjs",
"./tailwind.config": "./tailwind.config.ts",
- "./globals.css": "./dist/styles/globals.css",
+ "./global.css": "./dist/styles/global.css",
"./*": "./dist/*"
},
"dependencies": {
diff --git a/packages/ui/src/components/alert.tsx b/packages/ui/src/components/alert.tsx
new file mode 100644
index 0000000..4b121f2
--- /dev/null
+++ b/packages/ui/src/components/alert.tsx
@@ -0,0 +1,66 @@
+import * as React from "react"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@repo/ui/lib/utils"
+
+const alertVariants = cva(
+ "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
+ {
+ variants: {
+ variant: {
+ default: "bg-card text-card-foreground",
+ destructive:
+ "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+)
+
+function Alert({
+ className,
+ variant,
+ ...props
+}: React.ComponentProps<"div"> & VariantProps) {
+ return (
+
+ )
+}
+
+function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+function AlertDescription({
+ className,
+ ...props
+}: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export { Alert, AlertTitle, AlertDescription }
diff --git a/packages/ui/src/components/badge.tsx b/packages/ui/src/components/badge.tsx
new file mode 100644
index 0000000..006d0f4
--- /dev/null
+++ b/packages/ui/src/components/badge.tsx
@@ -0,0 +1,46 @@
+import * as React from "react"
+import { Slot } from "@radix-ui/react-slot"
+import { cva, type VariantProps } from "class-variance-authority"
+
+import { cn } from "@repo/ui/lib/utils"
+
+const badgeVariants = cva(
+ "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
+ {
+ variants: {
+ variant: {
+ default:
+ "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
+ destructive:
+ "border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
+ outline:
+ "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+)
+
+function Badge({
+ className,
+ variant,
+ asChild = false,
+ ...props
+}: React.ComponentProps<"span"> &
+ VariantProps & { asChild?: boolean }) {
+ const Comp = asChild ? Slot : "span"
+
+ return (
+
+ )
+}
+
+export { Badge, badgeVariants }
diff --git a/packages/ui/src/styles/globals.css b/packages/ui/src/styles/global.css
similarity index 100%
rename from packages/ui/src/styles/globals.css
rename to packages/ui/src/styles/global.css