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.
Files changed (2) hide show
  1. package/dist/cli.js +158 -6
  2. 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
- Create interactive previews in your docs by adding React components
994
- to the previews/ directory:
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 # React component (entry)
999
- styles.css # Optional 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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prev-cli",
3
- "version": "0.12.4",
3
+ "version": "0.13.1",
4
4
  "description": "Transform MDX directories into beautiful documentation websites",
5
5
  "type": "module",
6
6
  "license": "MIT",