revine 0.3.4 → 0.4.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/dist/commands/createProject.js +1 -1
- package/dist/config/vite.js +2 -2
- package/dist/setup/dependencies.js +15 -0
- package/dist/setup/tailwind.js +121 -11
- package/package.json +1 -1
- package/src/commands/createProject.ts +1 -1
- package/src/config/vite.ts +3 -3
- package/src/setup/tailwind.ts +122 -15
- package/template/.revine/bundler/defaults/vite.ts +1 -2
- package/template/.revine/bundler/generateConfig.ts +9 -9
- package/template/.revine/bundler/utils/loadUserConfig.ts +1 -1
- package/template/.revine/bundler/vite.config.ts +1 -1
- package/template/package.json +1 -0
- package/template/src/pages/index.tsx +58 -4
- package/template/src/root.tsx +1 -0
- package/template/src/styles/global.css +150 -0
- /package/src/{installers → setup}/dependencies.ts +0 -0
|
@@ -2,7 +2,7 @@ import path from "path";
|
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
3
|
import { updatePackageJson } from "../config/package.js";
|
|
4
4
|
import { updateReadme } from "../config/readme.js";
|
|
5
|
-
import { installDependencies } from "../
|
|
5
|
+
import { installDependencies } from "../setup/dependencies.js";
|
|
6
6
|
import { askForTailwindSetup } from "../prompts/tailwind.js";
|
|
7
7
|
import { setupTailwind } from "../setup/tailwind.js";
|
|
8
8
|
import { copyTemplate } from "../utils/file.js";
|
package/dist/config/vite.js
CHANGED
|
@@ -2,8 +2,8 @@ import fs from "fs-extra";
|
|
|
2
2
|
export async function updateViteConfig(filePath) {
|
|
3
3
|
let viteConfigContent = await fs.readFile(filePath, "utf-8");
|
|
4
4
|
// Insert Tailwind import after the React plugin import.
|
|
5
|
-
viteConfigContent = viteConfigContent.replace(
|
|
5
|
+
viteConfigContent = viteConfigContent.replace('import react from "@vitejs/plugin-react";', "import react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';");
|
|
6
6
|
// Insert Tailwind plugin into the plugins array.
|
|
7
|
-
viteConfigContent = viteConfigContent.replace("plugins: [react()]", "plugins: [\n react(),\n tailwindcss()\n ]");
|
|
7
|
+
viteConfigContent = viteConfigContent.replace("plugins: [react(), revineLoggerPlugin()]", "plugins: [\n react(),\n revineLoggerPlugin(),\n tailwindcss()\n ]");
|
|
8
8
|
await fs.writeFile(filePath, viteConfigContent);
|
|
9
9
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { spawnSync } from "child_process";
|
|
2
|
+
import { logError, logInfo } from "../utils/logger.js";
|
|
3
|
+
export async function installDependencies(projectDir) {
|
|
4
|
+
const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
5
|
+
const installResult = spawnSync(npmCmd, ["install"], {
|
|
6
|
+
stdio: "inherit",
|
|
7
|
+
cwd: projectDir,
|
|
8
|
+
shell: true,
|
|
9
|
+
});
|
|
10
|
+
if (installResult.error || installResult.status !== 0) {
|
|
11
|
+
logError("Error installing dependencies:", installResult.error);
|
|
12
|
+
logInfo("Try running manually: npm install");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
}
|
package/dist/setup/tailwind.js
CHANGED
|
@@ -5,16 +5,126 @@ import { logInfo } from "../utils/logger.js";
|
|
|
5
5
|
export async function setupTailwind(projectDir) {
|
|
6
6
|
logInfo("\nSetting up Tailwind CSS...");
|
|
7
7
|
// Point to the hidden Vite config
|
|
8
|
-
const viteConfigPath = path.join(projectDir, ".revine", "bundler", "vite.
|
|
9
|
-
//
|
|
8
|
+
const viteConfigPath = path.join(projectDir, ".revine", "bundler", "defaults", "vite.ts");
|
|
9
|
+
// Use existing updateViteConfig logic on this new path
|
|
10
10
|
await updateViteConfig(viteConfigPath);
|
|
11
|
-
//
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
await fs.writeFile(
|
|
15
|
-
//
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
// Write the Tailwind CSS import into the existing global.css file
|
|
12
|
+
const cssFile = path.join(projectDir, "src", "styles", "global.css");
|
|
13
|
+
const cssFileContent = `@import 'tailwindcss';\n`;
|
|
14
|
+
await fs.writeFile(cssFile, cssFileContent);
|
|
15
|
+
// Update the starter file for Tailwind classes
|
|
16
|
+
const starterFile = path.join(projectDir, "src", "pages", "index.tsx");
|
|
17
|
+
const starterFileContent = `
|
|
18
|
+
export default function HomePage() {
|
|
19
|
+
return (
|
|
20
|
+
<main className="flex min-h-screen flex-col items-center justify-center p-6 bg-gradient-to-b from-white via-white to-indigo-200">
|
|
21
|
+
{/* Hero Section */}
|
|
22
|
+
<div className="max-w-screen-lg w-full text-center space-y-6">
|
|
23
|
+
<h1 className="text-4xl sm:text-6xl font-extrabold text-gray-900 tracking-tight leading-tight">
|
|
24
|
+
Welcome to{" "}
|
|
25
|
+
<span className="text-transparent bg-clip-text bg-gradient-to-r from-indigo-500 via-indigo-600 to-black">
|
|
26
|
+
Revine
|
|
27
|
+
</span>
|
|
28
|
+
</h1>
|
|
29
|
+
<p className="text-xl sm:text-2xl text-gray-600 font-light">
|
|
30
|
+
The modern, powerful, and streamlined React framework.
|
|
31
|
+
</p>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
{/* CTA Buttons */}
|
|
35
|
+
<div className="mt-8 flex space-x-4">
|
|
36
|
+
<a
|
|
37
|
+
href="#get-started"
|
|
38
|
+
className="rounded-md bg-indigo-600 px-6 py-3 text-white font-semibold shadow-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-colors"
|
|
39
|
+
>
|
|
40
|
+
Get Started
|
|
41
|
+
</a>
|
|
42
|
+
<a
|
|
43
|
+
href="#docs"
|
|
44
|
+
className="rounded-md bg-white px-6 py-3 text-indigo-600 font-semibold border border-indigo-200 shadow hover:bg-gray-100 transition-colors focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
45
|
+
>
|
|
46
|
+
Read Docs
|
|
47
|
+
</a>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
{/* Features Section */}
|
|
51
|
+
<div className="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3 max-w-screen-lg w-full">
|
|
52
|
+
<a
|
|
53
|
+
href="#fast"
|
|
54
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
55
|
+
>
|
|
56
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
57
|
+
Lightning Fast
|
|
58
|
+
</h3>
|
|
59
|
+
<p className="text-gray-600">
|
|
60
|
+
Built on Vite for ultra-fast development and instant HMR.
|
|
61
|
+
</p>
|
|
62
|
+
</a>
|
|
63
|
+
|
|
64
|
+
<a
|
|
65
|
+
href="#routing"
|
|
66
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
67
|
+
>
|
|
68
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
69
|
+
Simple File-based Routing
|
|
70
|
+
</h3>
|
|
71
|
+
<p className="text-gray-600">
|
|
72
|
+
Create pages in <code>src/pages</code> and Revine will handle the
|
|
73
|
+
rest.
|
|
74
|
+
</p>
|
|
75
|
+
</a>
|
|
76
|
+
|
|
77
|
+
<a
|
|
78
|
+
href="#tailwind"
|
|
79
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
80
|
+
>
|
|
81
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
82
|
+
Tailwind Integration
|
|
83
|
+
</h3>
|
|
84
|
+
<p className="text-gray-600">
|
|
85
|
+
Pre-configured for Tailwind CSS, so you can style quickly and
|
|
86
|
+
easily.
|
|
87
|
+
</p>
|
|
88
|
+
</a>
|
|
89
|
+
|
|
90
|
+
<a
|
|
91
|
+
href="#dev-experience"
|
|
92
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
93
|
+
>
|
|
94
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">Great DX</h3>
|
|
95
|
+
<p className="text-gray-600">
|
|
96
|
+
Minimal config, fast builds, custom logging, and more.
|
|
97
|
+
</p>
|
|
98
|
+
</a>
|
|
99
|
+
|
|
100
|
+
<a
|
|
101
|
+
href="#abstract"
|
|
102
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
103
|
+
>
|
|
104
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
105
|
+
Abstracted Internals
|
|
106
|
+
</h3>
|
|
107
|
+
<p className="text-gray-600">
|
|
108
|
+
A .revine folder houses the complex Vite config. Keep your root
|
|
109
|
+
clean.
|
|
110
|
+
</p>
|
|
111
|
+
</a>
|
|
112
|
+
|
|
113
|
+
<a
|
|
114
|
+
href="#customize"
|
|
115
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
116
|
+
>
|
|
117
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
118
|
+
Fully Customizable
|
|
119
|
+
</h3>
|
|
120
|
+
<p className="text-gray-600">
|
|
121
|
+
Easily extend or override settings in <code>revine.config.ts</code>.
|
|
122
|
+
</p>
|
|
123
|
+
</a>
|
|
124
|
+
</div>
|
|
125
|
+
</main>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
`;
|
|
129
|
+
await fs.writeFile(starterFile, starterFileContent);
|
|
20
130
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import path from "path";
|
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
3
|
import { updatePackageJson } from "../config/package.js";
|
|
4
4
|
import { updateReadme } from "../config/readme.js";
|
|
5
|
-
import { installDependencies } from "../
|
|
5
|
+
import { installDependencies } from "../setup/dependencies.js";
|
|
6
6
|
import { askForTailwindSetup } from "../prompts/tailwind.js";
|
|
7
7
|
import { setupTailwind } from "../setup/tailwind.js";
|
|
8
8
|
import { copyTemplate } from "../utils/file.js";
|
package/src/config/vite.ts
CHANGED
|
@@ -5,14 +5,14 @@ export async function updateViteConfig(filePath: string) {
|
|
|
5
5
|
|
|
6
6
|
// Insert Tailwind import after the React plugin import.
|
|
7
7
|
viteConfigContent = viteConfigContent.replace(
|
|
8
|
-
|
|
8
|
+
'import react from "@vitejs/plugin-react";',
|
|
9
9
|
"import react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';"
|
|
10
10
|
);
|
|
11
11
|
|
|
12
12
|
// Insert Tailwind plugin into the plugins array.
|
|
13
13
|
viteConfigContent = viteConfigContent.replace(
|
|
14
|
-
"plugins: [react()]",
|
|
15
|
-
"plugins: [\n react(),\n tailwindcss()\n ]"
|
|
14
|
+
"plugins: [react(), revineLoggerPlugin()]",
|
|
15
|
+
"plugins: [\n react(),\n revineLoggerPlugin(),\n tailwindcss()\n ]"
|
|
16
16
|
);
|
|
17
17
|
|
|
18
18
|
await fs.writeFile(filePath, viteConfigContent);
|
package/src/setup/tailwind.ts
CHANGED
|
@@ -11,24 +11,131 @@ export async function setupTailwind(projectDir: string) {
|
|
|
11
11
|
projectDir,
|
|
12
12
|
".revine",
|
|
13
13
|
"bundler",
|
|
14
|
-
"
|
|
14
|
+
"defaults",
|
|
15
|
+
"vite.ts"
|
|
15
16
|
);
|
|
16
17
|
|
|
17
|
-
//
|
|
18
|
+
// Use existing updateViteConfig logic on this new path
|
|
18
19
|
await updateViteConfig(viteConfigPath);
|
|
19
20
|
|
|
20
|
-
//
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
await fs.writeFile(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
);
|
|
21
|
+
// Write the Tailwind CSS import into the existing global.css file
|
|
22
|
+
const cssFile = path.join(projectDir, "src", "styles", "global.css");
|
|
23
|
+
const cssFileContent = `@import 'tailwindcss';\n`;
|
|
24
|
+
await fs.writeFile(cssFile, cssFileContent);
|
|
25
|
+
|
|
26
|
+
// Update the starter file for Tailwind classes
|
|
27
|
+
const starterFile = path.join(projectDir, "src", "pages", "index.tsx");
|
|
28
|
+
const starterFileContent = `
|
|
29
|
+
export default function HomePage() {
|
|
30
|
+
return (
|
|
31
|
+
<main className="flex min-h-screen flex-col items-center justify-center p-6 bg-gradient-to-b from-white via-white to-indigo-200">
|
|
32
|
+
{/* Hero Section */}
|
|
33
|
+
<div className="max-w-screen-lg w-full text-center space-y-6">
|
|
34
|
+
<h1 className="text-4xl sm:text-6xl font-extrabold text-gray-900 tracking-tight leading-tight">
|
|
35
|
+
Welcome to{" "}
|
|
36
|
+
<span className="text-transparent bg-clip-text bg-gradient-to-r from-indigo-500 via-indigo-600 to-black">
|
|
37
|
+
Revine
|
|
38
|
+
</span>
|
|
39
|
+
</h1>
|
|
40
|
+
<p className="text-xl sm:text-2xl text-gray-600 font-light">
|
|
41
|
+
The modern, powerful, and streamlined React framework.
|
|
42
|
+
</p>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
{/* CTA Buttons */}
|
|
46
|
+
<div className="mt-8 flex space-x-4">
|
|
47
|
+
<a
|
|
48
|
+
href="#get-started"
|
|
49
|
+
className="rounded-md bg-indigo-600 px-6 py-3 text-white font-semibold shadow-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-colors"
|
|
50
|
+
>
|
|
51
|
+
Get Started
|
|
52
|
+
</a>
|
|
53
|
+
<a
|
|
54
|
+
href="#docs"
|
|
55
|
+
className="rounded-md bg-white px-6 py-3 text-indigo-600 font-semibold border border-indigo-200 shadow hover:bg-gray-100 transition-colors focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
|
56
|
+
>
|
|
57
|
+
Read Docs
|
|
58
|
+
</a>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
{/* Features Section */}
|
|
62
|
+
<div className="mt-12 grid gap-6 sm:grid-cols-2 lg:grid-cols-3 max-w-screen-lg w-full">
|
|
63
|
+
<a
|
|
64
|
+
href="#fast"
|
|
65
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
66
|
+
>
|
|
67
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
68
|
+
Lightning Fast
|
|
69
|
+
</h3>
|
|
70
|
+
<p className="text-gray-600">
|
|
71
|
+
Built on Vite for ultra-fast development and instant HMR.
|
|
72
|
+
</p>
|
|
73
|
+
</a>
|
|
74
|
+
|
|
75
|
+
<a
|
|
76
|
+
href="#routing"
|
|
77
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
78
|
+
>
|
|
79
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
80
|
+
Simple File-based Routing
|
|
81
|
+
</h3>
|
|
82
|
+
<p className="text-gray-600">
|
|
83
|
+
Create pages in <code>src/pages</code> and Revine will handle the
|
|
84
|
+
rest.
|
|
85
|
+
</p>
|
|
86
|
+
</a>
|
|
27
87
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
88
|
+
<a
|
|
89
|
+
href="#tailwind"
|
|
90
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
91
|
+
>
|
|
92
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
93
|
+
Tailwind Integration
|
|
94
|
+
</h3>
|
|
95
|
+
<p className="text-gray-600">
|
|
96
|
+
Pre-configured for Tailwind CSS, so you can style quickly and
|
|
97
|
+
easily.
|
|
98
|
+
</p>
|
|
99
|
+
</a>
|
|
100
|
+
|
|
101
|
+
<a
|
|
102
|
+
href="#dev-experience"
|
|
103
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
104
|
+
>
|
|
105
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">Great DX</h3>
|
|
106
|
+
<p className="text-gray-600">
|
|
107
|
+
Minimal config, fast builds, custom logging, and more.
|
|
108
|
+
</p>
|
|
109
|
+
</a>
|
|
110
|
+
|
|
111
|
+
<a
|
|
112
|
+
href="#abstract"
|
|
113
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
114
|
+
>
|
|
115
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
116
|
+
Abstracted Internals
|
|
117
|
+
</h3>
|
|
118
|
+
<p className="text-gray-600">
|
|
119
|
+
A .revine folder houses the complex Vite config. Keep your root
|
|
120
|
+
clean.
|
|
121
|
+
</p>
|
|
122
|
+
</a>
|
|
123
|
+
|
|
124
|
+
<a
|
|
125
|
+
href="#customize"
|
|
126
|
+
className="block rounded-xl border border-gray-200 bg-white p-6 shadow transition hover:shadow-xl hover:-translate-y-1"
|
|
127
|
+
>
|
|
128
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">
|
|
129
|
+
Fully Customizable
|
|
130
|
+
</h3>
|
|
131
|
+
<p className="text-gray-600">
|
|
132
|
+
Easily extend or override settings in <code>revine.config.ts</code>.
|
|
133
|
+
</p>
|
|
134
|
+
</a>
|
|
135
|
+
</div>
|
|
136
|
+
</main>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
`;
|
|
140
|
+
await fs.writeFile(starterFile, starterFileContent);
|
|
34
141
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import react from "@vitejs/plugin-react";
|
|
2
2
|
import { revineLoggerPlugin } from "../viteLoggerPlugin";
|
|
3
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
4
3
|
|
|
5
4
|
export const defaultViteConfig = {
|
|
6
|
-
plugins: [react(), revineLoggerPlugin()
|
|
5
|
+
plugins: [react(), revineLoggerPlugin()],
|
|
7
6
|
logLevel: "silent",
|
|
8
7
|
|
|
9
8
|
server: {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { merge } from "lodash-es";
|
|
2
|
+
import { defaultViteConfig } from "./defaults/vite.js";
|
|
3
|
+
import { loadUserConfig } from "./utils/loadUserConfig.js";
|
|
4
|
+
|
|
5
|
+
interface UserConfig {
|
|
6
|
+
vite?: Record<string, unknown>;
|
|
7
|
+
}
|
|
6
8
|
|
|
7
9
|
export async function generateRevineViteConfig() {
|
|
8
10
|
// Load the user's revine.config.ts
|
|
9
|
-
const userConfig = await loadUserConfig();
|
|
11
|
+
const userConfig = (await loadUserConfig()) as UserConfig;
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
// Merge user "vite" overrides with your default config
|
|
12
15
|
const finalConfig = merge({}, defaultViteConfig, userConfig.vite || {});
|
|
13
16
|
|
|
14
|
-
// Insert the Tailwind plugin, if desired, automatically or conditionally:
|
|
15
|
-
// finalConfig.plugins.push(tailwindcss());
|
|
16
|
-
|
|
17
17
|
return finalConfig;
|
|
18
18
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export async function loadUserConfig() {
|
|
2
2
|
try {
|
|
3
3
|
// relative path to the user's revine.config.ts
|
|
4
|
-
const configModule = await import("../../../revine.config
|
|
4
|
+
const configModule = await import("../../../revine.config");
|
|
5
5
|
return configModule.default || {};
|
|
6
6
|
} catch (error) {
|
|
7
7
|
console.error(
|
package/template/package.json
CHANGED
|
@@ -1,8 +1,62 @@
|
|
|
1
1
|
export default function HomePage() {
|
|
2
2
|
return (
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
<
|
|
6
|
-
|
|
3
|
+
<main>
|
|
4
|
+
{/* Hero Section */}
|
|
5
|
+
<div>
|
|
6
|
+
<h1>
|
|
7
|
+
Welcome to <span>Revine</span>
|
|
8
|
+
</h1>
|
|
9
|
+
<p>The modern, powerful, and streamlined React framework.</p>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
{/* CTA Buttons */}
|
|
13
|
+
<div className="cta">
|
|
14
|
+
<a href="#get-started" className="primary-btn">
|
|
15
|
+
Get Started
|
|
16
|
+
</a>
|
|
17
|
+
<a href="#docs" className="secondary-btn">
|
|
18
|
+
Read Docs
|
|
19
|
+
</a>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
{/* Features Section */}
|
|
23
|
+
<div className="features">
|
|
24
|
+
<a href="#fast">
|
|
25
|
+
<h3>Lightning Fast</h3>
|
|
26
|
+
<p>Built on Vite for ultra-fast development and instant HMR.</p>
|
|
27
|
+
</a>
|
|
28
|
+
<a href="#routing">
|
|
29
|
+
<h3>Simple File-based Routing</h3>
|
|
30
|
+
<p>
|
|
31
|
+
Create pages in <code>src/pages</code> and Revine will handle the
|
|
32
|
+
rest.
|
|
33
|
+
</p>
|
|
34
|
+
</a>
|
|
35
|
+
<a href="#tailwind">
|
|
36
|
+
<h3>Tailwind Integration</h3>
|
|
37
|
+
<p>
|
|
38
|
+
Pre-configured for Tailwind CSS, so you can style quickly and
|
|
39
|
+
easily.
|
|
40
|
+
</p>
|
|
41
|
+
</a>
|
|
42
|
+
<a href="#dev-experience">
|
|
43
|
+
<h3>Great DX</h3>
|
|
44
|
+
<p>Minimal config, fast builds, custom logging, and more.</p>
|
|
45
|
+
</a>
|
|
46
|
+
<a href="#abstract">
|
|
47
|
+
<h3>Abstracted Internals</h3>
|
|
48
|
+
<p>
|
|
49
|
+
A .revine folder houses the complex Vite config. Keep your root
|
|
50
|
+
clean.
|
|
51
|
+
</p>
|
|
52
|
+
</a>
|
|
53
|
+
<a href="#customize">
|
|
54
|
+
<h3>Fully Customizable</h3>
|
|
55
|
+
<p>
|
|
56
|
+
Easily extend or override settings in <code>revine.config.ts</code>.
|
|
57
|
+
</p>
|
|
58
|
+
</a>
|
|
59
|
+
</div>
|
|
60
|
+
</main>
|
|
7
61
|
);
|
|
8
62
|
}
|
package/template/src/root.tsx
CHANGED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--gradient-from: #ffffff;
|
|
3
|
+
--gradient-via: #ffffff;
|
|
4
|
+
--gradient-to: #d1d5db;
|
|
5
|
+
|
|
6
|
+
--text-primary: #111827;
|
|
7
|
+
--text-secondary: #4b5563;
|
|
8
|
+
--background-primary: #ffffff;
|
|
9
|
+
--border-color: #d1d5db;
|
|
10
|
+
|
|
11
|
+
--primary-color: #4f46e5;
|
|
12
|
+
--primary-hover: #4338ca;
|
|
13
|
+
--button-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
14
|
+
--button-hover-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
body {
|
|
18
|
+
margin: 0;
|
|
19
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
|
20
|
+
"Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif;
|
|
21
|
+
line-height: 1.5;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
main {
|
|
25
|
+
display: flex;
|
|
26
|
+
min-height: 100vh;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: center;
|
|
30
|
+
padding: 1.5rem;
|
|
31
|
+
background: linear-gradient(
|
|
32
|
+
to bottom,
|
|
33
|
+
var(--gradient-from),
|
|
34
|
+
var(--gradient-via),
|
|
35
|
+
var(--gradient-to)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
h1 {
|
|
40
|
+
font-size: 3rem;
|
|
41
|
+
line-height: 1.25;
|
|
42
|
+
font-weight: 800;
|
|
43
|
+
color: var(--text-primary);
|
|
44
|
+
text-align: center;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
h1 span {
|
|
48
|
+
background: linear-gradient(
|
|
49
|
+
to right,
|
|
50
|
+
var(--primary-color),
|
|
51
|
+
var(--primary-hover),
|
|
52
|
+
#000
|
|
53
|
+
);
|
|
54
|
+
-webkit-background-clip: text;
|
|
55
|
+
color: transparent;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
p {
|
|
59
|
+
font-size: 1.25rem;
|
|
60
|
+
color: var(--text-secondary);
|
|
61
|
+
text-align: center;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.cta {
|
|
65
|
+
display: flex;
|
|
66
|
+
gap: 1rem;
|
|
67
|
+
margin-top: 2rem;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.cta a {
|
|
71
|
+
padding: 0.75rem 1.5rem;
|
|
72
|
+
border-radius: 0.375rem;
|
|
73
|
+
font-weight: 600;
|
|
74
|
+
text-align: center;
|
|
75
|
+
text-decoration: none;
|
|
76
|
+
display: inline-block;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.cta .primary-btn {
|
|
80
|
+
background-color: var(--primary-color);
|
|
81
|
+
color: white;
|
|
82
|
+
box-shadow: var(--button-shadow);
|
|
83
|
+
transition: background-color 0.2s, box-shadow 0.2s;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.cta .primary-btn:hover {
|
|
87
|
+
background-color: var(--primary-hover);
|
|
88
|
+
box-shadow: var(--button-hover-shadow);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.cta .secondary-btn {
|
|
92
|
+
background-color: var(--background-primary);
|
|
93
|
+
color: var(--primary-color);
|
|
94
|
+
border: 1px solid var(--border-color);
|
|
95
|
+
box-shadow: var(--button-shadow);
|
|
96
|
+
transition: background-color 0.2s, box-shadow 0.2s;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.cta .secondary-btn:hover {
|
|
100
|
+
background-color: #f9fafb;
|
|
101
|
+
box-shadow: var(--button-hover-shadow);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.features {
|
|
105
|
+
display: grid;
|
|
106
|
+
grid-template-columns: repeat(1, 1fr);
|
|
107
|
+
gap: 1.5rem;
|
|
108
|
+
margin-top: 3rem;
|
|
109
|
+
max-width: 64rem;
|
|
110
|
+
width: 100%;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@media (min-width: 640px) {
|
|
114
|
+
.features {
|
|
115
|
+
grid-template-columns: repeat(2, 1fr);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@media (min-width: 1024px) {
|
|
120
|
+
.features {
|
|
121
|
+
grid-template-columns: repeat(3, 1fr);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.features a {
|
|
126
|
+
display: block;
|
|
127
|
+
padding: 1.5rem;
|
|
128
|
+
border: 1px solid var(--border-color);
|
|
129
|
+
border-radius: 0.75rem;
|
|
130
|
+
background-color: var(--background-primary);
|
|
131
|
+
text-decoration: none;
|
|
132
|
+
transition: box-shadow 0.2s, transform 0.2s;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.features a:hover {
|
|
136
|
+
box-shadow: var(--button-hover-shadow);
|
|
137
|
+
transform: translateY(-0.25rem);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.features h3 {
|
|
141
|
+
margin-bottom: 0.5rem;
|
|
142
|
+
font-size: 1.125rem;
|
|
143
|
+
font-weight: 600;
|
|
144
|
+
color: var(--text-primary);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.features p {
|
|
148
|
+
font-size: 0.875rem;
|
|
149
|
+
color: var(--text-secondary);
|
|
150
|
+
}
|
|
File without changes
|