@unciatech/file-manager 0.0.32 → 0.0.33
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 +125 -32
- package/dist/cli.cjs +120 -92
- package/dist/cli.js +115 -87
- package/dist/index.cjs +257 -170
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +243 -156
- package/dist/{mock-provider-nCBvw7nl.d.cts → mock-provider-DrtiUc3h.d.cts} +32 -4
- package/dist/{mock-provider-nCBvw7nl.d.ts → mock-provider-DrtiUc3h.d.ts} +32 -4
- package/dist/mock.d.cts +1 -1
- package/dist/mock.d.ts +1 -1
- package/dist/styles.css +75 -56
- package/dist/styles.d.ts +1 -0
- package/package.json +8 -5
- package/styles.css +75 -56
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 🗂️ File Manager
|
|
2
2
|
|
|
3
|
-
A robust, production-ready
|
|
3
|
+
A robust, production-ready file management component for any **React** application — works with Vite, Next.js, Remix, CRA, and more.
|
|
4
4
|
|
|
5
5
|
It supports deep folder nesting, drag-and-drop file uploads, metadata management for various file types (Images, Videos, Audio, Documents), unified grid layouts, and fully optimized loading states.
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ It supports deep folder nesting, drag-and-drop file uploads, metadata management
|
|
|
14
14
|
- **Graceful Error Handling**: Resilient `<FileManagerErrorBoundary>` that captures catastrophic failures and allows users to hard-reload safely without app crashes.
|
|
15
15
|
|
|
16
16
|
## 🛠️ Tech Stack
|
|
17
|
-
- **Framework**: Next.js
|
|
17
|
+
- **Framework**: React (any — Vite, Next.js, Remix, CRA)
|
|
18
18
|
- **Styling**: Tailwind CSS
|
|
19
19
|
- **Icons**: Custom SVG Icons
|
|
20
20
|
- **Notifications**: Sonner
|
|
@@ -22,9 +22,32 @@ It supports deep folder nesting, drag-and-drop file uploads, metadata management
|
|
|
22
22
|
> [!WARNING]
|
|
23
23
|
> This library is currently in **BETA**. Please report any bugs or feature requests on the GitHub issues page.
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## Setup & Requirements
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
Because this library relies heavily on Tailwind CSS for minimal zero-config styling, ensure your app is configured to scan the library's components for Tailwind utility classes.
|
|
28
|
+
|
|
29
|
+
### Tailwind v4
|
|
30
|
+
If you are using **Tailwind CSS v4** (like in newer Next.js or Vite projects), add this to your main CSS file (`globals.css` or `index.css`). This pulls in the required theme configuration and ensures the library is scanned:
|
|
31
|
+
|
|
32
|
+
```css
|
|
33
|
+
@import "tailwindcss";
|
|
34
|
+
@import "@unciatech/file-manager/styles";
|
|
35
|
+
@source "../node_modules/@unciatech/file-manager";
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Tailwind v3
|
|
39
|
+
If you are still on **Tailwind v3**, add the library path to your `tailwind.config.ts`:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
content: [
|
|
43
|
+
// ... your other paths
|
|
44
|
+
"./node_modules/@unciatech/file-manager/dist/**/*.{js,ts,jsx,tsx}",
|
|
45
|
+
],
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Basic Usage in Your Project
|
|
49
|
+
|
|
50
|
+
If you want to integrate this File Manager into your own React application (Next.js, Vite, Remix, CRA, etc.), follow this step-by-step guide.
|
|
28
51
|
|
|
29
52
|
### Step 1: Install the Package
|
|
30
53
|
|
|
@@ -46,30 +69,6 @@ The init script includes this automatically, but if you are installing manually,
|
|
|
46
69
|
import '@unciatech/file-manager/styles';
|
|
47
70
|
```
|
|
48
71
|
|
|
49
|
-
**(CRITICAL) Configure Tailwind CSS:**
|
|
50
|
-
Because this library uses Tailwind CSS, you MUST tell your Tailwind compiler to scan the library components for utility classes, otherwise it will render with zero styles!
|
|
51
|
-
|
|
52
|
-
**For Tailwind v3 (`tailwind.config.ts`):**
|
|
53
|
-
```typescript
|
|
54
|
-
import type { Config } from "tailwindcss";
|
|
55
|
-
|
|
56
|
-
const config: Config = {
|
|
57
|
-
content: [
|
|
58
|
-
// Your existing paths...
|
|
59
|
-
"./node_modules/@unciatech/file-manager/dist/**/*.js",
|
|
60
|
-
"./node_modules/@unciatech/file-manager/dist/**/*.mjs",
|
|
61
|
-
],
|
|
62
|
-
// ...
|
|
63
|
-
};
|
|
64
|
-
export default config;
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**For Tailwind v4 (`globals.css`):**
|
|
68
|
-
```css
|
|
69
|
-
@import "tailwindcss";
|
|
70
|
-
@source "../node_modules/@unciatech/file-manager/dist";
|
|
71
|
-
```
|
|
72
|
-
|
|
73
72
|
### Step 2: Create your Custom API Provider
|
|
74
73
|
|
|
75
74
|
The file manager is completely agnostic to your backend database. You simply need to create a class that implements the `IFileManagerProvider` interface.
|
|
@@ -129,10 +128,11 @@ export class MyCustomApiProvider implements IFileManagerProvider {
|
|
|
129
128
|
> If you are just prototyping and don't have a backend ready yet, you can skip Step 2 entirely! We included a fully functional `MockProvider` that fakes network latency and stores data in memory. Just import it and use it right away to see the UI in action.
|
|
130
129
|
|
|
131
130
|
// app/media/page.tsx
|
|
132
|
-
import {
|
|
133
|
-
import
|
|
134
|
-
import { MockProvider } from "@/providers/mock-provider";
|
|
131
|
+
import { FileManager, MockProvider } from "@unciatech/file-manager";
|
|
132
|
+
import "@unciatech/file-manager/styles";
|
|
135
133
|
|
|
134
|
+
// **Tailwind v4 Users:** Make sure your `globals.css` or `index.css` includes:
|
|
135
|
+
// @source "../node_modules/@unciatech/file-manager";
|
|
136
136
|
// OR import your real provider
|
|
137
137
|
import { MyCustomApiProvider } from "@/lib/my-api-provider";
|
|
138
138
|
|
|
@@ -148,7 +148,7 @@ export default function MediaLibraryPage() {
|
|
|
148
148
|
allowedFileTypes={["images", "videos", "audios", "files"]}
|
|
149
149
|
provider={apiProvider}
|
|
150
150
|
>
|
|
151
|
-
<FileManager />
|
|
151
|
+
<FileManager basePath="/media" />
|
|
152
152
|
</FileManagerProvider>
|
|
153
153
|
</div>
|
|
154
154
|
);
|
|
@@ -157,6 +157,99 @@ export default function MediaLibraryPage() {
|
|
|
157
157
|
|
|
158
158
|
---
|
|
159
159
|
|
|
160
|
+
## 🔀 Framework Router Integration
|
|
161
|
+
|
|
162
|
+
By default, the file manager uses the browser's native `history.pushState` API for navigation — no full page reloads, no dependencies. This works out of the box in any bare React app (Vite, CRA, etc.).
|
|
163
|
+
|
|
164
|
+
However, if your app already has its own router (React Router, Next.js, TanStack Router), you should pass the `onNavigate` prop so the file manager delegates all navigation to your router instead of calling `history.pushState` directly. This keeps your router's internal state in sync.
|
|
165
|
+
|
|
166
|
+
### React Router v6
|
|
167
|
+
|
|
168
|
+
```tsx
|
|
169
|
+
import { useNavigate } from 'react-router-dom';
|
|
170
|
+
|
|
171
|
+
function MyPage() {
|
|
172
|
+
const navigate = useNavigate();
|
|
173
|
+
|
|
174
|
+
return (
|
|
175
|
+
<FileManager
|
|
176
|
+
provider={provider}
|
|
177
|
+
allowedFileTypes={['images', 'videos']}
|
|
178
|
+
onNavigate={(url) => navigate(url)}
|
|
179
|
+
basePath="/media"
|
|
180
|
+
/>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Next.js (App Router)
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
'use client';
|
|
189
|
+
import { useRouter } from 'next/navigation';
|
|
190
|
+
|
|
191
|
+
export default function MediaPage() {
|
|
192
|
+
const router = useRouter();
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<FileManager
|
|
196
|
+
provider={provider}
|
|
197
|
+
allowedFileTypes={['images', 'videos']}
|
|
198
|
+
onNavigate={(url) => router.push(url)}
|
|
199
|
+
basePath="/media"
|
|
200
|
+
/>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### TanStack Router
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
import { useRouter } from '@tanstack/react-router';
|
|
209
|
+
|
|
210
|
+
function MyPage() {
|
|
211
|
+
const router = useRouter();
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<FileManager
|
|
215
|
+
provider={provider}
|
|
216
|
+
allowedFileTypes={['images', 'videos']}
|
|
217
|
+
onNavigate={(url) => router.navigate({ href: url })}
|
|
218
|
+
basePath="/media"
|
|
219
|
+
/>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
<FileManager
|
|
226
|
+
provider={provider}
|
|
227
|
+
allowedFileTypes={['images', 'videos']}
|
|
228
|
+
basePath="/media"
|
|
229
|
+
// no onNavigate needed
|
|
230
|
+
/>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## 🎮 Playgrounds & Reference Implementations
|
|
234
|
+
|
|
235
|
+
For complete, working examples of how to integrate the File Manager into different application architectures, check out the [playgrounds](file:///Users/avi/Developer/Uncia/file-manager/playgrounds) directory. These are fully functional Vite-based projects that demonstrate real-world integration patterns.
|
|
236
|
+
|
|
237
|
+
- **[React Router v7 Playground](file:///Users/avi/Developer/Uncia/file-manager/playgrounds/test-react-router)**: Demonstrates integration with `react-router-dom` using `useNavigate` and route-based navigation.
|
|
238
|
+
- **[TanStack Router Playground](file:///Users/avi/Developer/Uncia/file-manager/playgrounds/test-tanstack)**: Demonstrates integration with `@tanstack/react-router` using the `router` object and `href` based navigation.
|
|
239
|
+
|
|
240
|
+
These playgrounds are a great starting point for seeing how to handle:
|
|
241
|
+
- Styling with Tailwind CSS v4
|
|
242
|
+
- Mapping `onNavigate` to your framework's router
|
|
243
|
+
- Using the `MockProvider` for rapid prototyping
|
|
244
|
+
- Configuring `FileManagerModal` v/s full-page `FileManager`
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
> [!NOTE]
|
|
249
|
+
> The `onNavigate` prop is also available on `<FileManagerModal>` for modal mode.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
160
253
|
## 💾 Database Schema Design
|
|
161
254
|
|
|
162
255
|
Because this application relies heavily on tree structures (Folders inside Folders) and varied JSON metadata (Video durations vs Document page counts), using a relational database with JSONB support (like PostgreSQL) is highly recommended.
|
package/dist/cli.cjs
CHANGED
|
@@ -24,25 +24,27 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// cli.ts
|
|
27
|
-
var
|
|
28
|
-
var
|
|
27
|
+
var import_fs = __toESM(require("fs"), 1);
|
|
28
|
+
var import_path = __toESM(require("path"), 1);
|
|
29
29
|
var import_child_process = require("child_process");
|
|
30
|
-
var
|
|
30
|
+
var import_readline = __toESM(require("readline"), 1);
|
|
31
31
|
var args = process.argv.slice(2);
|
|
32
32
|
var command = args[0];
|
|
33
33
|
var projectName = args[1];
|
|
34
|
-
var rl =
|
|
34
|
+
var rl = import_readline.default.createInterface({
|
|
35
35
|
input: process.stdin,
|
|
36
36
|
output: process.stdout
|
|
37
37
|
});
|
|
38
|
-
var askQuestion = (query) =>
|
|
39
|
-
|
|
38
|
+
var askQuestion = (query) => {
|
|
39
|
+
return new Promise((resolve) => rl.question(query, resolve));
|
|
40
|
+
};
|
|
41
|
+
var getTemplate = (basePath = "/media") => `"use client";
|
|
40
42
|
|
|
41
|
-
import React, { Suspense
|
|
43
|
+
import React, { Suspense } from "react";
|
|
42
44
|
import { FileManager, MockProvider } from "@unciatech/file-manager";
|
|
43
45
|
|
|
44
46
|
export default function FileManagerDemo() {
|
|
45
|
-
const
|
|
47
|
+
const mockProvider = new MockProvider();
|
|
46
48
|
|
|
47
49
|
return (
|
|
48
50
|
<div className="h-screen w-full">
|
|
@@ -50,7 +52,8 @@ export default function FileManagerDemo() {
|
|
|
50
52
|
<FileManager
|
|
51
53
|
allowedFileTypes={["audios", "videos", "images", "files"]}
|
|
52
54
|
viewMode="grid"
|
|
53
|
-
provider={
|
|
55
|
+
provider={mockProvider}
|
|
56
|
+
basePath="${basePath}"
|
|
54
57
|
/>
|
|
55
58
|
</Suspense>
|
|
56
59
|
</div>
|
|
@@ -63,30 +66,39 @@ async function main() {
|
|
|
63
66
|
process.exit(0);
|
|
64
67
|
}
|
|
65
68
|
if (!projectName) {
|
|
66
|
-
console.log("\u{1F680} Generating <FileManagerDemo /> component...");
|
|
69
|
+
console.log("\u{1F680} Generating <FileManagerDemo /> component in the current project...");
|
|
67
70
|
let targetDir2 = process.cwd();
|
|
68
|
-
if (
|
|
69
|
-
targetDir2 =
|
|
70
|
-
} else if (
|
|
71
|
-
targetDir2 =
|
|
71
|
+
if (import_fs.default.existsSync(import_path.default.join(process.cwd(), "components"))) {
|
|
72
|
+
targetDir2 = import_path.default.join(process.cwd(), "components");
|
|
73
|
+
} else if (import_fs.default.existsSync(import_path.default.join(process.cwd(), "src", "components"))) {
|
|
74
|
+
targetDir2 = import_path.default.join(process.cwd(), "src", "components");
|
|
75
|
+
}
|
|
76
|
+
const targetFile = import_path.default.join(targetDir2, "FileManagerDemo.tsx");
|
|
77
|
+
if (import_fs.default.existsSync(targetFile)) {
|
|
78
|
+
console.error(`\u274C Error: ${targetFile} already exists.`);
|
|
79
|
+
process.exit(1);
|
|
72
80
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
console.log(
|
|
81
|
+
import_fs.default.writeFileSync(targetFile, getTemplate("/"), "utf-8");
|
|
82
|
+
console.log(`\u2705 Success! Created ${targetFile}`);
|
|
83
|
+
console.log("");
|
|
84
|
+
console.log("You can now import and render <FileManagerDemo /> anywhere in your application.");
|
|
85
|
+
console.log("Don't forget to configure your Tailwind CSS content to scan the library for styles!");
|
|
76
86
|
process.exit(0);
|
|
77
87
|
}
|
|
78
88
|
console.log(`
|
|
79
|
-
\u{1F680} Initializing
|
|
89
|
+
\u{1F680} Initializing a new application: ${projectName}
|
|
80
90
|
`);
|
|
81
|
-
console.log("
|
|
82
|
-
console.log("1) Next.js");
|
|
83
|
-
console.log("2) Vite (React)");
|
|
84
|
-
console.log("3) Cancel");
|
|
85
|
-
const choice = await askQuestion("\nSelect option (1-3): ");
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
console.log("Which framework would you like to use?");
|
|
92
|
+
console.log(" 1) Next.js (App Router, Tailwind v4)");
|
|
93
|
+
console.log(" 2) Vite (React, Tailwind v4)");
|
|
94
|
+
console.log(" 3) Cancel");
|
|
95
|
+
const choice = await askQuestion("\nSelect an option (1-3): ");
|
|
96
|
+
const targetDir = import_path.default.join(process.cwd(), projectName);
|
|
97
|
+
if (import_fs.default.existsSync(targetDir)) {
|
|
98
|
+
console.error(`
|
|
99
|
+
\u274C Error: Directory "${projectName}" already exists in ${process.cwd()}.`);
|
|
100
|
+
console.error(` Please choose a different project name or delete the existing directory first.`);
|
|
101
|
+
rl.close();
|
|
90
102
|
process.exit(1);
|
|
91
103
|
}
|
|
92
104
|
try {
|
|
@@ -96,34 +108,40 @@ async function main() {
|
|
|
96
108
|
await scaffoldVite(projectName, targetDir);
|
|
97
109
|
} else {
|
|
98
110
|
console.log("Canceled.");
|
|
111
|
+
process.exit(0);
|
|
99
112
|
}
|
|
100
|
-
} catch (
|
|
101
|
-
console.error("\u274C
|
|
113
|
+
} catch (error) {
|
|
114
|
+
console.error("\n\u274C Scaffolding failed:", error);
|
|
115
|
+
process.exit(1);
|
|
102
116
|
}
|
|
117
|
+
process.exit(0);
|
|
103
118
|
}
|
|
104
119
|
async function scaffoldNextjs(projectName2, targetDir) {
|
|
105
|
-
console.log("\n\u{1F4E6} Creating Next.js
|
|
106
|
-
(0, import_child_process.execSync)(
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
);
|
|
110
|
-
|
|
111
|
-
(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
console.log("\n\u{1F4E6} Creating Next.js application (this may take a minute)...");
|
|
121
|
+
(0, import_child_process.execSync)(`npx create-next-app@latest ${projectName2} --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-npm`, { stdio: "inherit" });
|
|
122
|
+
console.log("\n\u{1F4E6} Installing dependencies (@unciatech/file-manager, tailwindcss-animate)...");
|
|
123
|
+
(0, import_child_process.execSync)("npm install @unciatech/file-manager tailwindcss-animate", { cwd: targetDir, stdio: "inherit" });
|
|
124
|
+
const componentsDir = import_path.default.join(targetDir, "src", "components");
|
|
125
|
+
if (!import_fs.default.existsSync(componentsDir)) import_fs.default.mkdirSync(componentsDir, { recursive: true });
|
|
126
|
+
import_fs.default.writeFileSync(import_path.default.join(componentsDir, "FileManagerDemo.tsx"), getTemplate("/media"), "utf-8");
|
|
127
|
+
const pagePath = import_path.default.join(targetDir, "src", "app", "page.tsx");
|
|
128
|
+
import_fs.default.writeFileSync(pagePath, `import FileManagerDemo from "@/components/FileManagerDemo";
|
|
129
|
+
|
|
130
|
+
export default function Home() {
|
|
131
|
+
return (
|
|
132
|
+
<main className="min-h-screen bg-neutral-50">
|
|
133
|
+
<FileManagerDemo />
|
|
134
|
+
</main>
|
|
120
135
|
);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
136
|
+
}
|
|
137
|
+
`);
|
|
138
|
+
const mediaRouteDir = import_path.default.join(targetDir, "src", "app", "media", "[[...path]]");
|
|
139
|
+
import_fs.default.mkdirSync(mediaRouteDir, { recursive: true });
|
|
140
|
+
import_fs.default.writeFileSync(
|
|
141
|
+
import_path.default.join(mediaRouteDir, "page.tsx"),
|
|
124
142
|
`import FileManagerDemo from "@/components/FileManagerDemo";
|
|
125
143
|
|
|
126
|
-
export default function
|
|
144
|
+
export default function MediaPage() {
|
|
127
145
|
return (
|
|
128
146
|
<main className="min-h-screen bg-neutral-50">
|
|
129
147
|
<FileManagerDemo />
|
|
@@ -132,49 +150,61 @@ export default function Home() {
|
|
|
132
150
|
}
|
|
133
151
|
`
|
|
134
152
|
);
|
|
153
|
+
const layoutPath = import_path.default.join(targetDir, "src", "app", "layout.tsx");
|
|
154
|
+
if (import_fs.default.existsSync(layoutPath)) {
|
|
155
|
+
let layoutContent = import_fs.default.readFileSync(layoutPath, "utf8");
|
|
156
|
+
if (!layoutContent.includes("@unciatech/file-manager/styles")) {
|
|
157
|
+
layoutContent = layoutContent.replace(
|
|
158
|
+
/^(import type)/m,
|
|
159
|
+
`import '@unciatech/file-manager/styles';
|
|
160
|
+
$1`
|
|
161
|
+
);
|
|
162
|
+
import_fs.default.writeFileSync(layoutPath, layoutContent);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const cssPath = import_path.default.join(targetDir, "src", "app", "globals.css");
|
|
166
|
+
import_fs.default.writeFileSync(cssPath, `@import "tailwindcss";
|
|
167
|
+
@import "@unciatech/file-manager/styles";
|
|
168
|
+
@import "tw-animate-css";
|
|
169
|
+
|
|
170
|
+
@source "../../node_modules/@unciatech/file-manager";
|
|
171
|
+
|
|
172
|
+
@theme {
|
|
173
|
+
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
174
|
+
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
175
|
+
}
|
|
176
|
+
`);
|
|
135
177
|
printSuccess(projectName2);
|
|
136
178
|
}
|
|
137
179
|
async function scaffoldVite(projectName2, targetDir) {
|
|
138
|
-
console.log("\n\u{1F4E6} Creating Vite
|
|
139
|
-
(0, import_child_process.execSync)(
|
|
140
|
-
|
|
141
|
-
{ stdio: "inherit" }
|
|
142
|
-
);
|
|
143
|
-
console.log("\n\u{1F4E6} Installing dependencies...");
|
|
180
|
+
console.log("\n\u{1F4E6} Creating Vite React application...");
|
|
181
|
+
(0, import_child_process.execSync)(`npm create vite@latest ${projectName2} -- --template react-ts`, { stdio: "inherit" });
|
|
182
|
+
console.log("\n\u{1F4E6} Installing dependencies (Tailwind + File Manager)...");
|
|
144
183
|
(0, import_child_process.execSync)("npm install", { cwd: targetDir, stdio: "inherit" });
|
|
145
|
-
(0, import_child_process.execSync)(
|
|
146
|
-
|
|
147
|
-
{ cwd: targetDir, stdio: "inherit" }
|
|
148
|
-
);
|
|
184
|
+
(0, import_child_process.execSync)("npm install tailwindcss @tailwindcss/vite @unciatech/file-manager", { cwd: targetDir, stdio: "inherit" });
|
|
185
|
+
const viteConfigPath = import_path.default.join(targetDir, "vite.config.ts");
|
|
149
186
|
const viteConfig = `import { defineConfig } from 'vite'
|
|
150
187
|
import react from '@vitejs/plugin-react'
|
|
151
188
|
import tailwindcss from '@tailwindcss/vite'
|
|
152
189
|
|
|
153
190
|
export default defineConfig({
|
|
154
|
-
plugins: [
|
|
191
|
+
plugins: [
|
|
192
|
+
react(),
|
|
193
|
+
tailwindcss(),
|
|
194
|
+
],
|
|
155
195
|
})
|
|
156
196
|
`;
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
@source "../node_modules/@unciatech/file-manager
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
` + main2;
|
|
169
|
-
}
|
|
170
|
-
fs.writeFileSync(mainFile, main2);
|
|
171
|
-
const compDir = path.join(targetDir, "src/components");
|
|
172
|
-
fs.mkdirSync(compDir, { recursive: true });
|
|
173
|
-
fs.writeFileSync(
|
|
174
|
-
path.join(compDir, "FileManagerDemo.tsx"),
|
|
175
|
-
TEMPLATE
|
|
176
|
-
);
|
|
177
|
-
const app = `import FileManagerDemo from "./components/FileManagerDemo";
|
|
197
|
+
import_fs.default.writeFileSync(viteConfigPath, viteConfig);
|
|
198
|
+
const cssPath = import_path.default.join(targetDir, "src", "index.css");
|
|
199
|
+
import_fs.default.writeFileSync(cssPath, `@import "tailwindcss";
|
|
200
|
+
@import "@unciatech/file-manager/styles";
|
|
201
|
+
@source "../node_modules/@unciatech/file-manager";
|
|
202
|
+
`);
|
|
203
|
+
const componentsDir = import_path.default.join(targetDir, "src", "components");
|
|
204
|
+
if (!import_fs.default.existsSync(componentsDir)) import_fs.default.mkdirSync(componentsDir, { recursive: true });
|
|
205
|
+
import_fs.default.writeFileSync(import_path.default.join(componentsDir, "FileManagerDemo.tsx"), getTemplate("/"), "utf-8");
|
|
206
|
+
const appPath = import_path.default.join(targetDir, "src", "App.tsx");
|
|
207
|
+
import_fs.default.writeFileSync(appPath, `import FileManagerDemo from "./components/FileManagerDemo";
|
|
178
208
|
|
|
179
209
|
function App() {
|
|
180
210
|
return (
|
|
@@ -185,18 +215,16 @@ function App() {
|
|
|
185
215
|
}
|
|
186
216
|
|
|
187
217
|
export default App;
|
|
188
|
-
`;
|
|
189
|
-
fs.writeFileSync(path.join(targetDir, "src/App.tsx"), app);
|
|
190
|
-
printSuccess(projectName2);
|
|
191
|
-
}
|
|
192
|
-
function printSuccess(projectName2) {
|
|
193
|
-
console.log("\n=================================");
|
|
194
|
-
console.log("\u{1F389} Project ready!");
|
|
195
|
-
console.log("=================================");
|
|
196
|
-
console.log(`
|
|
197
|
-
Next steps:`);
|
|
198
|
-
console.log(`cd ${projectName2}`);
|
|
199
|
-
console.log(`npm run dev
|
|
200
218
|
`);
|
|
219
|
+
printSuccess(projectName2, "npm run dev");
|
|
220
|
+
}
|
|
221
|
+
function printSuccess(projectName2, devCmd = "npm run dev") {
|
|
222
|
+
console.log("\n=========================================");
|
|
223
|
+
console.log("\u{1F389} Your Media Library application is ready!");
|
|
224
|
+
console.log("=========================================");
|
|
225
|
+
console.log("\nNext steps:");
|
|
226
|
+
console.log(` cd ${projectName2}`);
|
|
227
|
+
console.log(` ${devCmd}`);
|
|
228
|
+
console.log("\nEnjoy building! \u{1F5C2}\uFE0F\n");
|
|
201
229
|
}
|
|
202
230
|
main();
|