create-rv 0.1.0
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 +146 -0
- package/dist/cli.js +62 -0
- package/dist/cli.js.map +1 -0
- package/dist/copyDotfiles.js +30 -0
- package/dist/copyDotfiles.js.map +1 -0
- package/dist/git.js +14 -0
- package/dist/git.js.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/installers/eslint.js +17 -0
- package/dist/installers/eslint.js.map +1 -0
- package/dist/installers/index.js +46 -0
- package/dist/installers/index.js.map +1 -0
- package/dist/installers/prettier.js +11 -0
- package/dist/installers/prettier.js.map +1 -0
- package/dist/installers/query.js +8 -0
- package/dist/installers/query.js.map +1 -0
- package/dist/installers/rhf.js +9 -0
- package/dist/installers/rhf.js.map +1 -0
- package/dist/installers/router-react-router.js +6 -0
- package/dist/installers/router-react-router.js.map +1 -0
- package/dist/installers/router-tanstack.js +7 -0
- package/dist/installers/router-tanstack.js.map +1 -0
- package/dist/installers/router.js +10 -0
- package/dist/installers/router.js.map +1 -0
- package/dist/installers/shadcn.js +25 -0
- package/dist/installers/shadcn.js.map +1 -0
- package/dist/installers/zod.js +8 -0
- package/dist/installers/zod.js.map +1 -0
- package/dist/installers/zustand.js +8 -0
- package/dist/installers/zustand.js.map +1 -0
- package/dist/log.js +25 -0
- package/dist/log.js.map +1 -0
- package/dist/options.js +28 -0
- package/dist/options.js.map +1 -0
- package/dist/pkgManager.js +34 -0
- package/dist/pkgManager.js.map +1 -0
- package/dist/prompts.js +85 -0
- package/dist/prompts.js.map +1 -0
- package/dist/scaffold.js +211 -0
- package/dist/scaffold.js.map +1 -0
- package/package.json +55 -0
- package/templates/base/README.md +60 -0
- package/templates/base/js/index.html +13 -0
- package/templates/base/js/jsconfig.json +16 -0
- package/templates/base/js/package.json +22 -0
- package/templates/base/js/src/App.jsx +10 -0
- package/templates/base/js/src/index.css +6 -0
- package/templates/base/js/src/main.jsx +10 -0
- package/templates/base/js/vite.config.js +13 -0
- package/templates/base/ts/index.html +13 -0
- package/templates/base/ts/package.json +26 -0
- package/templates/base/ts/src/App.tsx +10 -0
- package/templates/base/ts/src/index.css +6 -0
- package/templates/base/ts/src/main.tsx +10 -0
- package/templates/base/ts/src/vite-env.d.ts +1 -0
- package/templates/base/ts/tsconfig.json +27 -0
- package/templates/base/ts/tsconfig.node.json +12 -0
- package/templates/base/ts/vite.config.ts +13 -0
- package/templates/extras/eslint/.eslintignore +3 -0
- package/templates/extras/eslint/eslint.config.js +37 -0
- package/templates/extras/prettier/.prettierignore +7 -0
- package/templates/extras/prettier/.prettierrc +8 -0
- package/templates/extras/query/src/main.tsx +15 -0
- package/templates/extras/rhf/src/components/ExampleForm.tsx +40 -0
- package/templates/extras/router-react-router/src/App.tsx +24 -0
- package/templates/extras/router-react-router/src/main.tsx +13 -0
- package/templates/extras/router-react-router/src/pages/about.tsx +7 -0
- package/templates/extras/router-react-router/src/pages/home.tsx +7 -0
- package/templates/extras/router-tanstack/src/main.tsx +19 -0
- package/templates/extras/router-tanstack/src/routes/__root.tsx +16 -0
- package/templates/extras/router-tanstack/src/routes/about.tsx +13 -0
- package/templates/extras/router-tanstack/src/routes/index.tsx +13 -0
- package/templates/extras/router-tanstack/vite.config.ts +18 -0
- package/templates/extras/shadcn/components.json +19 -0
- package/templates/extras/shadcn/src/components/ui/button.tsx +45 -0
- package/templates/extras/shadcn/src/components/ui/card.tsx +34 -0
- package/templates/extras/shadcn/src/components/ui/input.tsx +19 -0
- package/templates/extras/shadcn/src/index.css +85 -0
- package/templates/extras/shadcn/src/lib/utils.ts +6 -0
- package/templates/extras/zod/src/lib/schemas.ts +8 -0
- package/templates/extras/zustand/src/lib/store.ts +15 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [react(), tailwindcss()],
|
|
8
|
+
resolve: {
|
|
9
|
+
alias: {
|
|
10
|
+
"@": path.resolve(__dirname, "./src"),
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import vercel from "eslint-config-vercel";
|
|
2
|
+
import tsParser from "@typescript-eslint/parser";
|
|
3
|
+
import tsPlugin from "@typescript-eslint/eslint-plugin";
|
|
4
|
+
import reactPlugin from "eslint-plugin-react";
|
|
5
|
+
import reactHooks from "eslint-plugin-react-hooks";
|
|
6
|
+
import importPlugin from "eslint-plugin-import";
|
|
7
|
+
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
|
8
|
+
import tailwind from "eslint-plugin-tailwindcss";
|
|
9
|
+
|
|
10
|
+
export default [
|
|
11
|
+
...vercel,
|
|
12
|
+
{
|
|
13
|
+
files: ["**/*.{ts,tsx}"],
|
|
14
|
+
languageOptions: {
|
|
15
|
+
parser: tsParser,
|
|
16
|
+
parserOptions: { ecmaVersion: "latest", sourceType: "module", ecmaFeatures: { jsx: true } },
|
|
17
|
+
},
|
|
18
|
+
plugins: {
|
|
19
|
+
"@typescript-eslint": tsPlugin,
|
|
20
|
+
react: reactPlugin,
|
|
21
|
+
"react-hooks": reactHooks,
|
|
22
|
+
import: importPlugin,
|
|
23
|
+
"simple-import-sort": simpleImportSort,
|
|
24
|
+
tailwindcss: tailwind,
|
|
25
|
+
},
|
|
26
|
+
rules: {
|
|
27
|
+
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
|
|
28
|
+
"react-hooks/rules-of-hooks": "error",
|
|
29
|
+
"react-hooks/exhaustive-deps": "warn",
|
|
30
|
+
"simple-import-sort/imports": "warn",
|
|
31
|
+
"simple-import-sort/exports": "warn",
|
|
32
|
+
"tailwindcss/classnames-order": "warn",
|
|
33
|
+
},
|
|
34
|
+
settings: { react: { version: "detect" } },
|
|
35
|
+
},
|
|
36
|
+
{ ignores: ["dist", "node_modules", "*.config.js"] },
|
|
37
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
|
+
import App from "./App";
|
|
5
|
+
import "./index.css";
|
|
6
|
+
|
|
7
|
+
const queryClient = new QueryClient();
|
|
8
|
+
|
|
9
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
10
|
+
<React.StrictMode>
|
|
11
|
+
<QueryClientProvider client={queryClient}>
|
|
12
|
+
<App />
|
|
13
|
+
</QueryClientProvider>
|
|
14
|
+
</React.StrictMode>,
|
|
15
|
+
);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useForm } from "react-hook-form";
|
|
2
|
+
|
|
3
|
+
interface FormValues {
|
|
4
|
+
email: string;
|
|
5
|
+
password: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function ExampleForm() {
|
|
9
|
+
const { register, handleSubmit, formState } = useForm<FormValues>({
|
|
10
|
+
defaultValues: { email: "", password: "" },
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const onSubmit = handleSubmit((values) => {
|
|
14
|
+
console.log(values);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<form onSubmit={onSubmit} className="mx-auto max-w-sm space-y-4 p-6">
|
|
19
|
+
<input
|
|
20
|
+
{...register("email", { required: true })}
|
|
21
|
+
type="email"
|
|
22
|
+
placeholder="email"
|
|
23
|
+
className="w-full rounded border p-2"
|
|
24
|
+
/>
|
|
25
|
+
<input
|
|
26
|
+
{...register("password", { required: true })}
|
|
27
|
+
type="password"
|
|
28
|
+
placeholder="password"
|
|
29
|
+
className="w-full rounded border p-2"
|
|
30
|
+
/>
|
|
31
|
+
<button
|
|
32
|
+
type="submit"
|
|
33
|
+
disabled={formState.isSubmitting}
|
|
34
|
+
className="w-full rounded bg-black p-2 text-white"
|
|
35
|
+
>
|
|
36
|
+
submit
|
|
37
|
+
</button>
|
|
38
|
+
</form>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Link, Route, Routes } from "react-router";
|
|
2
|
+
import { HomePage } from "./pages/home";
|
|
3
|
+
import { AboutPage } from "./pages/about";
|
|
4
|
+
|
|
5
|
+
export default function App() {
|
|
6
|
+
return (
|
|
7
|
+
<div className="min-h-screen bg-background text-foreground">
|
|
8
|
+
<header className="border-b">
|
|
9
|
+
<nav className="container mx-auto flex h-14 items-center gap-4 px-4">
|
|
10
|
+
<Link to="/" className="font-semibold">
|
|
11
|
+
my-app
|
|
12
|
+
</Link>
|
|
13
|
+
<Link to="/about" className="text-muted-foreground">
|
|
14
|
+
about
|
|
15
|
+
</Link>
|
|
16
|
+
</nav>
|
|
17
|
+
</header>
|
|
18
|
+
<Routes>
|
|
19
|
+
<Route path="/" element={<HomePage />} />
|
|
20
|
+
<Route path="/about" element={<AboutPage />} />
|
|
21
|
+
</Routes>
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import { BrowserRouter } from "react-router";
|
|
4
|
+
import App from "./App";
|
|
5
|
+
import "./index.css";
|
|
6
|
+
|
|
7
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
8
|
+
<React.StrictMode>
|
|
9
|
+
<BrowserRouter>
|
|
10
|
+
<App />
|
|
11
|
+
</BrowserRouter>
|
|
12
|
+
</React.StrictMode>,
|
|
13
|
+
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import { createRouter, RouterProvider } from "@tanstack/react-router";
|
|
4
|
+
import { routeTree } from "./routeTree.gen";
|
|
5
|
+
import "./index.css";
|
|
6
|
+
|
|
7
|
+
const router = createRouter({ routeTree });
|
|
8
|
+
|
|
9
|
+
declare module "@tanstack/react-router" {
|
|
10
|
+
interface Register {
|
|
11
|
+
router: typeof router;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
16
|
+
<React.StrictMode>
|
|
17
|
+
<RouterProvider router={router} />
|
|
18
|
+
</React.StrictMode>,
|
|
19
|
+
);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Outlet, createRootRoute, Link } from "@tanstack/react-router";
|
|
2
|
+
|
|
3
|
+
export const Route = createRootRoute({
|
|
4
|
+
component: () => (
|
|
5
|
+
<div className="min-h-screen bg-background text-foreground">
|
|
6
|
+
<header className="border-b">
|
|
7
|
+
<nav className="container mx-auto flex h-14 items-center gap-4 px-4">
|
|
8
|
+
<Link to="/" className="font-semibold">
|
|
9
|
+
my-app
|
|
10
|
+
</Link>
|
|
11
|
+
</nav>
|
|
12
|
+
</header>
|
|
13
|
+
<Outlet />
|
|
14
|
+
</div>
|
|
15
|
+
),
|
|
16
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
2
|
+
|
|
3
|
+
export const Route = createFileRoute("/about")({
|
|
4
|
+
component: AboutPage,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
function AboutPage() {
|
|
8
|
+
return (
|
|
9
|
+
<main className="container mx-auto p-8">
|
|
10
|
+
<h1 className="text-3xl font-bold">about</h1>
|
|
11
|
+
</main>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
2
|
+
|
|
3
|
+
export const Route = createFileRoute("/")({
|
|
4
|
+
component: HomePage,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
function HomePage() {
|
|
8
|
+
return (
|
|
9
|
+
<main className="container mx-auto flex min-h-[calc(100vh-3.5rem)] items-center justify-center px-4">
|
|
10
|
+
<h1 className="text-4xl font-bold">welcome</h1>
|
|
11
|
+
</main>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
+
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
plugins: [
|
|
9
|
+
TanStackRouterVite({ target: "react", autoCodeSplitting: true }),
|
|
10
|
+
react(),
|
|
11
|
+
tailwindcss(),
|
|
12
|
+
],
|
|
13
|
+
resolve: {
|
|
14
|
+
alias: {
|
|
15
|
+
"@": path.resolve(__dirname, "./src"),
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema.json",
|
|
3
|
+
"style": "new-york",
|
|
4
|
+
"rsc": false,
|
|
5
|
+
"tsx": true,
|
|
6
|
+
"tailwind": {
|
|
7
|
+
"config": "",
|
|
8
|
+
"css": "src/index.css",
|
|
9
|
+
"baseColor": "neutral",
|
|
10
|
+
"cssVariables": true
|
|
11
|
+
},
|
|
12
|
+
"aliases": {
|
|
13
|
+
"components": "@/components",
|
|
14
|
+
"ui": "@/components/ui",
|
|
15
|
+
"lib": "@/lib",
|
|
16
|
+
"hooks": "@/hooks",
|
|
17
|
+
"utils": "@/lib/utils"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
const buttonVariants = cva(
|
|
7
|
+
"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",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
12
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
13
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
14
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
15
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
16
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
17
|
+
},
|
|
18
|
+
size: {
|
|
19
|
+
default: "h-10 px-4 py-2",
|
|
20
|
+
sm: "h-9 rounded-md px-3",
|
|
21
|
+
lg: "h-11 rounded-md px-8",
|
|
22
|
+
icon: "h-10 w-10",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
defaultVariants: { variant: "default", size: "default" },
|
|
26
|
+
},
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export interface ButtonProps
|
|
30
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
31
|
+
VariantProps<typeof buttonVariants> {
|
|
32
|
+
asChild?: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
36
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
37
|
+
const Comp = asChild ? Slot : "button";
|
|
38
|
+
return (
|
|
39
|
+
<Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />
|
|
40
|
+
);
|
|
41
|
+
},
|
|
42
|
+
);
|
|
43
|
+
Button.displayName = "Button";
|
|
44
|
+
|
|
45
|
+
export { buttonVariants };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
export const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
5
|
+
({ className, ...props }, ref) => (
|
|
6
|
+
<div
|
|
7
|
+
ref={ref}
|
|
8
|
+
className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}
|
|
9
|
+
{...props}
|
|
10
|
+
/>
|
|
11
|
+
),
|
|
12
|
+
);
|
|
13
|
+
Card.displayName = "Card";
|
|
14
|
+
|
|
15
|
+
export const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
16
|
+
({ className, ...props }, ref) => (
|
|
17
|
+
<div ref={ref} className={cn("flex flex-col space-y-1.5 p-6", className)} {...props} />
|
|
18
|
+
),
|
|
19
|
+
);
|
|
20
|
+
CardHeader.displayName = "CardHeader";
|
|
21
|
+
|
|
22
|
+
export const CardTitle = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
23
|
+
({ className, ...props }, ref) => (
|
|
24
|
+
<div ref={ref} className={cn("text-2xl font-semibold leading-none tracking-tight", className)} {...props} />
|
|
25
|
+
),
|
|
26
|
+
);
|
|
27
|
+
CardTitle.displayName = "CardTitle";
|
|
28
|
+
|
|
29
|
+
export const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
|
30
|
+
({ className, ...props }, ref) => (
|
|
31
|
+
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
|
|
32
|
+
),
|
|
33
|
+
);
|
|
34
|
+
CardContent.displayName = "CardContent";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cn } from "@/lib/utils";
|
|
3
|
+
|
|
4
|
+
export type InputProps = React.InputHTMLAttributes<HTMLInputElement>;
|
|
5
|
+
|
|
6
|
+
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
7
|
+
({ className, type, ...props }, ref) => (
|
|
8
|
+
<input
|
|
9
|
+
type={type}
|
|
10
|
+
ref={ref}
|
|
11
|
+
className={cn(
|
|
12
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
),
|
|
18
|
+
);
|
|
19
|
+
Input.displayName = "Input";
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@plugin "tailwindcss-animate";
|
|
3
|
+
|
|
4
|
+
@custom-variant dark (&:is(.dark *));
|
|
5
|
+
|
|
6
|
+
:root {
|
|
7
|
+
--background: oklch(1 0 0);
|
|
8
|
+
--foreground: oklch(0.145 0 0);
|
|
9
|
+
--card: oklch(1 0 0);
|
|
10
|
+
--card-foreground: oklch(0.145 0 0);
|
|
11
|
+
--popover: oklch(1 0 0);
|
|
12
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
13
|
+
--primary: oklch(0.205 0 0);
|
|
14
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
15
|
+
--secondary: oklch(0.97 0 0);
|
|
16
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
17
|
+
--muted: oklch(0.97 0 0);
|
|
18
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
19
|
+
--accent: oklch(0.97 0 0);
|
|
20
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
21
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
22
|
+
--destructive-foreground: oklch(0.985 0 0);
|
|
23
|
+
--border: oklch(0.922 0 0);
|
|
24
|
+
--input: oklch(0.922 0 0);
|
|
25
|
+
--ring: oklch(0.708 0 0);
|
|
26
|
+
--radius: 0.625rem;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.dark {
|
|
30
|
+
--background: oklch(0.145 0 0);
|
|
31
|
+
--foreground: oklch(0.985 0 0);
|
|
32
|
+
--card: oklch(0.205 0 0);
|
|
33
|
+
--card-foreground: oklch(0.985 0 0);
|
|
34
|
+
--popover: oklch(0.205 0 0);
|
|
35
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
36
|
+
--primary: oklch(0.922 0 0);
|
|
37
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
38
|
+
--secondary: oklch(0.269 0 0);
|
|
39
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
40
|
+
--muted: oklch(0.269 0 0);
|
|
41
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
42
|
+
--accent: oklch(0.269 0 0);
|
|
43
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
44
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
45
|
+
--destructive-foreground: oklch(0.985 0 0);
|
|
46
|
+
--border: oklch(1 0 0 / 10%);
|
|
47
|
+
--input: oklch(1 0 0 / 15%);
|
|
48
|
+
--ring: oklch(0.556 0 0);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@theme inline {
|
|
52
|
+
--color-background: var(--background);
|
|
53
|
+
--color-foreground: var(--foreground);
|
|
54
|
+
--color-card: var(--card);
|
|
55
|
+
--color-card-foreground: var(--card-foreground);
|
|
56
|
+
--color-popover: var(--popover);
|
|
57
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
58
|
+
--color-primary: var(--primary);
|
|
59
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
60
|
+
--color-secondary: var(--secondary);
|
|
61
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
62
|
+
--color-muted: var(--muted);
|
|
63
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
64
|
+
--color-accent: var(--accent);
|
|
65
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
66
|
+
--color-destructive: var(--destructive);
|
|
67
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
68
|
+
--color-border: var(--border);
|
|
69
|
+
--color-input: var(--input);
|
|
70
|
+
--color-ring: var(--ring);
|
|
71
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
72
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
73
|
+
--radius-lg: var(--radius);
|
|
74
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@layer base {
|
|
78
|
+
* { border-color: var(--color-border); }
|
|
79
|
+
body {
|
|
80
|
+
background-color: var(--color-background);
|
|
81
|
+
color: var(--color-foreground);
|
|
82
|
+
margin: 0;
|
|
83
|
+
font-family: ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { create } from "zustand";
|
|
2
|
+
|
|
3
|
+
interface CounterState {
|
|
4
|
+
count: number;
|
|
5
|
+
increment: () => void;
|
|
6
|
+
decrement: () => void;
|
|
7
|
+
reset: () => void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const useCounter = create<CounterState>((set) => ({
|
|
11
|
+
count: 0,
|
|
12
|
+
increment: () => set((s) => ({ count: s.count + 1 })),
|
|
13
|
+
decrement: () => set((s) => ({ count: s.count - 1 })),
|
|
14
|
+
reset: () => set({ count: 0 }),
|
|
15
|
+
}));
|