create-kalai-app 1.0.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/index.js +75 -0
- package/package.json +16 -0
- package/template/.env.example +4 -0
- package/template/_gitignore +25 -0
- package/template/index.html +17 -0
- package/template/package.json +36 -0
- package/template/postcss.config.cjs +6 -0
- package/template/src/app/App.tsx +12 -0
- package/template/src/features/_module-template/pages/TemplatePage.tsx +25 -0
- package/template/src/features/home/pages/HomePage.tsx +39 -0
- package/template/src/index.css +14 -0
- package/template/src/main.tsx +10 -0
- package/template/src/shared/lib/utils.ts +6 -0
- package/template/src/vite-env.d.ts +1 -0
- package/template/tailwind.config.cjs +11 -0
- package/template/tsconfig.json +25 -0
- package/template/vite.config.ts +14 -0
package/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const { execSync } = require("child_process");
|
|
6
|
+
|
|
7
|
+
const appName = process.argv[2];
|
|
8
|
+
|
|
9
|
+
if (!appName) {
|
|
10
|
+
console.error("Usage: npx create-kalai-app <app-name>");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const targetDir = path.resolve(process.cwd(), appName);
|
|
15
|
+
|
|
16
|
+
if (fs.existsSync(targetDir)) {
|
|
17
|
+
console.error(`Error: Directory "${appName}" already exists.`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const templateDir = path.join(__dirname, "template");
|
|
22
|
+
|
|
23
|
+
// Recursive copy
|
|
24
|
+
function copyDir(src, dest) {
|
|
25
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
26
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
27
|
+
const srcPath = path.join(src, entry.name);
|
|
28
|
+
const destPath = path.join(dest, entry.name);
|
|
29
|
+
if (entry.isDirectory()) {
|
|
30
|
+
copyDir(srcPath, destPath);
|
|
31
|
+
} else {
|
|
32
|
+
fs.copyFileSync(srcPath, destPath);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log(`\nCreating Kalai app in ${targetDir}...\n`);
|
|
38
|
+
|
|
39
|
+
// Copy template
|
|
40
|
+
copyDir(templateDir, targetDir);
|
|
41
|
+
|
|
42
|
+
// Update package.json name
|
|
43
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
44
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
45
|
+
pkg.name = appName;
|
|
46
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
47
|
+
|
|
48
|
+
// Rename _gitignore to .gitignore (npm strips .gitignore from published packages)
|
|
49
|
+
const gitignoreSrc = path.join(targetDir, "_gitignore");
|
|
50
|
+
if (fs.existsSync(gitignoreSrc)) {
|
|
51
|
+
fs.renameSync(gitignoreSrc, path.join(targetDir, ".gitignore"));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Install dependencies
|
|
55
|
+
console.log("Installing dependencies...\n");
|
|
56
|
+
try {
|
|
57
|
+
execSync("npm install", { cwd: targetDir, stdio: "inherit" });
|
|
58
|
+
} catch {
|
|
59
|
+
console.log("\nnpm install failed. Run it manually:\n");
|
|
60
|
+
console.log(` cd ${appName}`);
|
|
61
|
+
console.log(" npm install\n");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
console.log(`
|
|
65
|
+
Done! Your Kalai app is ready.
|
|
66
|
+
|
|
67
|
+
cd ${appName}
|
|
68
|
+
npm run dev
|
|
69
|
+
|
|
70
|
+
The app starts at http://localhost:5173 with:
|
|
71
|
+
- @kalaiworks/ui components
|
|
72
|
+
- @kalaiworks/tokens via CDN (auto-updates)
|
|
73
|
+
- @kalaiworks/config for Tailwind/ESLint/TypeScript
|
|
74
|
+
- Module template ready to copy at src/features/_module-template/
|
|
75
|
+
`);
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-kalai-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Scaffold a new app wired to the Kalai design system",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-kalai-app": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"index.js",
|
|
11
|
+
"template"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules
|
|
3
|
+
|
|
4
|
+
# Build output
|
|
5
|
+
dist
|
|
6
|
+
|
|
7
|
+
# Vite
|
|
8
|
+
.vite
|
|
9
|
+
|
|
10
|
+
# Test
|
|
11
|
+
coverage
|
|
12
|
+
|
|
13
|
+
# Environment
|
|
14
|
+
.env
|
|
15
|
+
.env.local
|
|
16
|
+
.env.development
|
|
17
|
+
.env.production
|
|
18
|
+
|
|
19
|
+
# OS
|
|
20
|
+
.DS_Store
|
|
21
|
+
Thumbs.db
|
|
22
|
+
|
|
23
|
+
# Editor
|
|
24
|
+
.vscode/settings.json
|
|
25
|
+
*.swp
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Kalai App</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
10
|
+
<!-- Kalai design tokens — updates automatically on @kalaiworks/tokens publish -->
|
|
11
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@kalaiworks/tokens@1/tokens.css" />
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div id="root"></div>
|
|
15
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
16
|
+
</body>
|
|
17
|
+
</html>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kalai-app",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc --noEmit && vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"typecheck": "tsc --noEmit"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@kalaiworks/ui": "^1.0.0",
|
|
14
|
+
"@kalaiworks/config": "^1.0.0",
|
|
15
|
+
"@radix-ui/react-slot": "^1.1.0",
|
|
16
|
+
"@tanstack/react-query": "^5.55.4",
|
|
17
|
+
"class-variance-authority": "^0.7.0",
|
|
18
|
+
"clsx": "^2.1.1",
|
|
19
|
+
"lucide-react": "^0.441.0",
|
|
20
|
+
"react": "^18.3.1",
|
|
21
|
+
"react-dom": "^18.3.1",
|
|
22
|
+
"react-router-dom": "^6.26.1",
|
|
23
|
+
"tailwind-merge": "^2.5.2"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/react": "^18.3.4",
|
|
27
|
+
"@types/react-dom": "^18.3.0",
|
|
28
|
+
"@vitejs/plugin-react": "^4.3.1",
|
|
29
|
+
"autoprefixer": "^10.4.20",
|
|
30
|
+
"postcss": "^8.4.41",
|
|
31
|
+
"tailwindcss": "^3.4.10",
|
|
32
|
+
"tailwindcss-animate": "^1.0.7",
|
|
33
|
+
"typescript": "^5.5.4",
|
|
34
|
+
"vite": "^5.4.2"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
|
2
|
+
import HomePage from "@/features/home/pages/HomePage";
|
|
3
|
+
|
|
4
|
+
export default function App() {
|
|
5
|
+
return (
|
|
6
|
+
<BrowserRouter>
|
|
7
|
+
<Routes>
|
|
8
|
+
<Route path="/" element={<HomePage />} />
|
|
9
|
+
</Routes>
|
|
10
|
+
</BrowserRouter>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module Template
|
|
3
|
+
*
|
|
4
|
+
* Copy this entire `_module-template` folder and rename it to create a new
|
|
5
|
+
* feature module. Then add a route in src/app/App.tsx.
|
|
6
|
+
*
|
|
7
|
+
* Recommended structure:
|
|
8
|
+
* features/<name>/
|
|
9
|
+
* pages/ — route-level page components
|
|
10
|
+
* components/ — feature-specific UI components
|
|
11
|
+
* hooks/ — feature-specific React hooks
|
|
12
|
+
* api/ — API functions (TanStack Query)
|
|
13
|
+
* types/ — TypeScript types for this feature
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export default function TemplatePage() {
|
|
17
|
+
return (
|
|
18
|
+
<div className="p-6">
|
|
19
|
+
<h1 className="text-2xl font-semibold">Module Template</h1>
|
|
20
|
+
<p className="mt-2 text-muted-foreground">
|
|
21
|
+
Replace this with your feature content.
|
|
22
|
+
</p>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export default function HomePage() {
|
|
2
|
+
return (
|
|
3
|
+
<div className="flex min-h-screen items-center justify-center bg-background">
|
|
4
|
+
<div className="mx-auto max-w-lg text-center">
|
|
5
|
+
<h1 className="text-4xl font-bold tracking-tight text-foreground">
|
|
6
|
+
Welcome to Kalai
|
|
7
|
+
</h1>
|
|
8
|
+
<p className="mt-4 text-muted-foreground">
|
|
9
|
+
Your app is wired to the Kalai design system. Edit{" "}
|
|
10
|
+
<code className="rounded bg-muted px-1.5 py-0.5 text-sm font-mono">
|
|
11
|
+
src/features/home/pages/HomePage.tsx
|
|
12
|
+
</code>{" "}
|
|
13
|
+
to get started.
|
|
14
|
+
</p>
|
|
15
|
+
<div className="mt-8 flex justify-center gap-3">
|
|
16
|
+
<a
|
|
17
|
+
href="https://github.com/nicholasgmail/kalai-DesignSystem"
|
|
18
|
+
target="_blank"
|
|
19
|
+
rel="noopener noreferrer"
|
|
20
|
+
className="inline-flex h-10 items-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground hover:bg-primary/90"
|
|
21
|
+
>
|
|
22
|
+
Documentation
|
|
23
|
+
</a>
|
|
24
|
+
<a
|
|
25
|
+
href="https://www.npmjs.com/org/kalaiworks"
|
|
26
|
+
target="_blank"
|
|
27
|
+
rel="noopener noreferrer"
|
|
28
|
+
className="inline-flex h-10 items-center rounded-md border border-input bg-background px-4 text-sm font-medium hover:bg-accent hover:text-accent-foreground"
|
|
29
|
+
>
|
|
30
|
+
npm Packages
|
|
31
|
+
</a>
|
|
32
|
+
</div>
|
|
33
|
+
<p className="mt-6 text-xs text-muted-foreground">
|
|
34
|
+
Copy <code className="font-mono">src/features/_module-template/</code> to create new feature modules.
|
|
35
|
+
</p>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const preset = require("@kalaiworks/config/tailwind-preset.cjs");
|
|
2
|
+
|
|
3
|
+
/** @type {import('tailwindcss').Config} */
|
|
4
|
+
module.exports = {
|
|
5
|
+
presets: [preset],
|
|
6
|
+
content: [
|
|
7
|
+
"./index.html",
|
|
8
|
+
"./src/**/*.{ts,tsx}",
|
|
9
|
+
"./node_modules/@kalaiworks/ui/dist/**/*.{js,cjs}",
|
|
10
|
+
],
|
|
11
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
"isolatedModules": true,
|
|
11
|
+
"moduleDetection": "force",
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"jsx": "react-jsx",
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUnusedLocals": true,
|
|
16
|
+
"noUnusedParameters": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"types": ["vite/client"],
|
|
19
|
+
"baseUrl": ".",
|
|
20
|
+
"paths": {
|
|
21
|
+
"@/*": ["src/*"]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"include": ["src", "vite.config.ts"]
|
|
25
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [react()],
|
|
7
|
+
resolve: {
|
|
8
|
+
alias: {
|
|
9
|
+
"@": path.resolve(__dirname, "./src"),
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
// When connecting a real backend, add a proxy here:
|
|
13
|
+
// server: { proxy: { "/api": { target: "http://localhost:8001", changeOrigin: true } } }
|
|
14
|
+
});
|