prev-cli 0.12.4 → 0.13.1
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/cli.js +158 -6
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { parseArgs } from "util";
|
|
5
5
|
import path7 from "path";
|
|
6
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
6
7
|
|
|
7
8
|
// src/vite/start.ts
|
|
8
9
|
import { createServer as createServer2, build as build2, preview } from "vite";
|
|
@@ -980,6 +981,7 @@ Usage:
|
|
|
980
981
|
prev [options] Start development server
|
|
981
982
|
prev build [options] Build for production
|
|
982
983
|
prev preview [options] Preview production build
|
|
984
|
+
prev create [name] Create preview in previews/<name>/ (default: "example")
|
|
983
985
|
prev clean [options] Remove old cache directories
|
|
984
986
|
|
|
985
987
|
Options:
|
|
@@ -990,13 +992,13 @@ Options:
|
|
|
990
992
|
-h, --help Show this help message
|
|
991
993
|
|
|
992
994
|
Previews:
|
|
993
|
-
|
|
994
|
-
|
|
995
|
+
Previews must be in the previews/ directory at your project root.
|
|
996
|
+
Each preview is a subfolder with React components:
|
|
995
997
|
|
|
996
|
-
previews/
|
|
997
|
-
my-demo/
|
|
998
|
-
App.tsx
|
|
999
|
-
styles.css
|
|
998
|
+
previews/ # Required location
|
|
999
|
+
my-demo/ # Preview name (used in <Preview src="...">)
|
|
1000
|
+
App.tsx # React component (entry point)
|
|
1001
|
+
styles.css # Optional CSS
|
|
1000
1002
|
|
|
1001
1003
|
Then embed in MDX:
|
|
1002
1004
|
import { Preview } from '@prev/theme'
|
|
@@ -1023,10 +1025,156 @@ Examples:
|
|
|
1023
1025
|
prev Start dev server on random port
|
|
1024
1026
|
prev -p 3000 Start dev server on port 3000
|
|
1025
1027
|
prev build Build static site to ./dist
|
|
1028
|
+
prev create Create example preview in previews/example/
|
|
1029
|
+
prev create my-demo Create preview in previews/my-demo/
|
|
1026
1030
|
prev -i .c3 Include .c3 directory in docs
|
|
1027
1031
|
prev clean -d 7 Remove caches older than 7 days
|
|
1028
1032
|
`);
|
|
1029
1033
|
}
|
|
1034
|
+
function createPreview(rootDir2, name) {
|
|
1035
|
+
const previewDir = path7.join(rootDir2, "previews", name);
|
|
1036
|
+
if (existsSync5(previewDir)) {
|
|
1037
|
+
console.error(`Preview "${name}" already exists at: ${previewDir}`);
|
|
1038
|
+
process.exit(1);
|
|
1039
|
+
}
|
|
1040
|
+
mkdirSync2(previewDir, { recursive: true });
|
|
1041
|
+
const appTsx = `import { useState } from 'react'
|
|
1042
|
+
import './styles.css'
|
|
1043
|
+
|
|
1044
|
+
export default function App() {
|
|
1045
|
+
const [count, setCount] = useState(0)
|
|
1046
|
+
const [items, setItems] = useState<string[]>([])
|
|
1047
|
+
|
|
1048
|
+
const addItem = () => {
|
|
1049
|
+
setItems([...items, \`Item \${items.length + 1}\`])
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
return (
|
|
1053
|
+
<div className="min-h-screen bg-gradient-to-br from-indigo-50 to-purple-100 p-8">
|
|
1054
|
+
<div className="max-w-md mx-auto space-y-6">
|
|
1055
|
+
{/* Header */}
|
|
1056
|
+
<div className="text-center animate-fade-in">
|
|
1057
|
+
<h1 className="text-3xl font-bold text-gray-800">
|
|
1058
|
+
Preview Demo
|
|
1059
|
+
</h1>
|
|
1060
|
+
<p className="text-gray-600 mt-2">
|
|
1061
|
+
React + TypeScript + Tailwind
|
|
1062
|
+
</p>
|
|
1063
|
+
</div>
|
|
1064
|
+
|
|
1065
|
+
{/* Counter Card */}
|
|
1066
|
+
<div className="bg-white rounded-xl shadow-lg p-6 animate-fade-in">
|
|
1067
|
+
<h2 className="text-lg font-semibold text-gray-700 mb-4">Counter</h2>
|
|
1068
|
+
<div className="flex items-center justify-center gap-4">
|
|
1069
|
+
<button
|
|
1070
|
+
onClick={() => setCount(c => c - 1)}
|
|
1071
|
+
className="w-12 h-12 rounded-full bg-red-500 hover:bg-red-600 text-white text-xl font-bold transition-colors"
|
|
1072
|
+
>
|
|
1073
|
+
-
|
|
1074
|
+
</button>
|
|
1075
|
+
<span className="text-4xl font-mono font-bold text-gray-800 w-16 text-center">
|
|
1076
|
+
{count}
|
|
1077
|
+
</span>
|
|
1078
|
+
<button
|
|
1079
|
+
onClick={() => setCount(c => c + 1)}
|
|
1080
|
+
className="w-12 h-12 rounded-full bg-green-500 hover:bg-green-600 text-white text-xl font-bold transition-colors"
|
|
1081
|
+
>
|
|
1082
|
+
+
|
|
1083
|
+
</button>
|
|
1084
|
+
</div>
|
|
1085
|
+
</div>
|
|
1086
|
+
|
|
1087
|
+
{/* Dynamic List Card */}
|
|
1088
|
+
<div className="bg-white rounded-xl shadow-lg p-6 animate-fade-in">
|
|
1089
|
+
<div className="flex items-center justify-between mb-4">
|
|
1090
|
+
<h2 className="text-lg font-semibold text-gray-700">Dynamic List</h2>
|
|
1091
|
+
<button
|
|
1092
|
+
onClick={addItem}
|
|
1093
|
+
className="px-3 py-1 bg-indigo-500 hover:bg-indigo-600 text-white text-sm rounded-lg transition-colors"
|
|
1094
|
+
>
|
|
1095
|
+
Add Item
|
|
1096
|
+
</button>
|
|
1097
|
+
</div>
|
|
1098
|
+
{items.length === 0 ? (
|
|
1099
|
+
<p className="text-gray-400 text-center py-4">No items yet</p>
|
|
1100
|
+
) : (
|
|
1101
|
+
<ul className="space-y-2">
|
|
1102
|
+
{items.map((item, i) => (
|
|
1103
|
+
<li
|
|
1104
|
+
key={i}
|
|
1105
|
+
className="px-3 py-2 bg-gray-50 rounded-lg text-gray-700 animate-slide-in"
|
|
1106
|
+
>
|
|
1107
|
+
{item}
|
|
1108
|
+
</li>
|
|
1109
|
+
))}
|
|
1110
|
+
</ul>
|
|
1111
|
+
)}
|
|
1112
|
+
</div>
|
|
1113
|
+
|
|
1114
|
+
{/* Info Box */}
|
|
1115
|
+
<div className="bg-indigo-50 border border-indigo-200 rounded-lg p-4 text-sm text-indigo-700">
|
|
1116
|
+
<strong>Tip:</strong> Use the DevTools pill (bottom-right) to test
|
|
1117
|
+
responsive layouts and dark mode.
|
|
1118
|
+
</div>
|
|
1119
|
+
</div>
|
|
1120
|
+
</div>
|
|
1121
|
+
)
|
|
1122
|
+
}
|
|
1123
|
+
`;
|
|
1124
|
+
const stylesCss = `/* Custom animations for the preview */
|
|
1125
|
+
@keyframes fade-in {
|
|
1126
|
+
from {
|
|
1127
|
+
opacity: 0;
|
|
1128
|
+
transform: translateY(-10px);
|
|
1129
|
+
}
|
|
1130
|
+
to {
|
|
1131
|
+
opacity: 1;
|
|
1132
|
+
transform: translateY(0);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
@keyframes slide-in {
|
|
1137
|
+
from {
|
|
1138
|
+
opacity: 0;
|
|
1139
|
+
transform: translateX(-10px);
|
|
1140
|
+
}
|
|
1141
|
+
to {
|
|
1142
|
+
opacity: 1;
|
|
1143
|
+
transform: translateX(0);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
.animate-fade-in {
|
|
1148
|
+
animation: fade-in 0.3s ease-out;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
.animate-slide-in {
|
|
1152
|
+
animation: slide-in 0.2s ease-out;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/* Dark mode support */
|
|
1156
|
+
@media (prefers-color-scheme: dark) {
|
|
1157
|
+
.dark\\:bg-gray-900 { background-color: #111827; }
|
|
1158
|
+
.dark\\:text-white { color: #fff; }
|
|
1159
|
+
}
|
|
1160
|
+
`;
|
|
1161
|
+
writeFileSync3(path7.join(previewDir, "App.tsx"), appTsx);
|
|
1162
|
+
writeFileSync3(path7.join(previewDir, "styles.css"), stylesCss);
|
|
1163
|
+
console.log(`
|
|
1164
|
+
✨ Created preview: previews/${name}/
|
|
1165
|
+
|
|
1166
|
+
Files:
|
|
1167
|
+
previews/${name}/App.tsx React component (entry point)
|
|
1168
|
+
previews/${name}/styles.css Custom animations
|
|
1169
|
+
|
|
1170
|
+
Embed in your MDX:
|
|
1171
|
+
import { Preview } from '@prev/theme'
|
|
1172
|
+
<Preview src="${name}" />
|
|
1173
|
+
|
|
1174
|
+
Start dev server:
|
|
1175
|
+
prev
|
|
1176
|
+
`);
|
|
1177
|
+
}
|
|
1030
1178
|
async function main() {
|
|
1031
1179
|
if (values.help) {
|
|
1032
1180
|
printHelp();
|
|
@@ -1050,6 +1198,10 @@ async function main() {
|
|
|
1050
1198
|
const removed = await cleanCache({ maxAgeDays: days });
|
|
1051
1199
|
console.log(`Removed ${removed} cache(s) older than ${days} days`);
|
|
1052
1200
|
break;
|
|
1201
|
+
case "create":
|
|
1202
|
+
const previewName = positionals[1] || "example";
|
|
1203
|
+
createPreview(rootDir, previewName);
|
|
1204
|
+
break;
|
|
1053
1205
|
default:
|
|
1054
1206
|
console.error(`Unknown command: ${command}`);
|
|
1055
1207
|
printHelp();
|