@unciatech/file-manager 0.0.39 → 0.0.40
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.cjs +57 -70
- package/dist/cli.js +57 -70
- package/package.json +4 -3
- package/bin/file-manager.js +0 -3
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var
|
|
2
|
+
'use strict';var e=require('fs'),t=require('path'),child_process=require('child_process'),x=require('readline');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var e__default=/*#__PURE__*/_interopDefault(e);var t__default=/*#__PURE__*/_interopDefault(t);var x__default=/*#__PURE__*/_interopDefault(x);var u=process.argv.slice(2),h=u[0],r=u[1],f=x__default.default.createInterface({input:process.stdin,output:process.stdout}),w=o=>new Promise(i=>f.question(o,i)),y=(o="/media")=>`"use client";
|
|
3
3
|
|
|
4
4
|
import React, { Suspense } from "react";
|
|
5
5
|
import { FileManager, MockProvider } from "@unciatech/file-manager";
|
|
@@ -20,21 +20,21 @@ export default function FileManagerDemo() {
|
|
|
20
20
|
</div>
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
|
-
`;async function
|
|
24
|
-
\u{1F680} Initializing a new application: ${
|
|
25
|
-
`),console.log("Which framework would you like to use?"),console.log(" 1) Next.js (App Router, Tailwind v4)"),console.log(" 2) Vite (React, Tailwind v4)"),console.log(" 3) Cancel");let o=await
|
|
26
|
-
Select an option (1-3): `),
|
|
27
|
-
\u274C Error: Directory "${
|
|
28
|
-
\u274C Scaffolding failed:`,s),process.exit(1);}process.exit(0);}async function
|
|
23
|
+
`;async function b(){if(h!=="init"&&(console.log("Usage: npx @unciatech/file-manager init [project-name]"),process.exit(0)),!r){console.log("\u{1F680} Generating <FileManagerDemo /> component in the current project...");let s=process.cwd();e__default.default.existsSync(t__default.default.join(process.cwd(),"components"))?s=t__default.default.join(process.cwd(),"components"):e__default.default.existsSync(t__default.default.join(process.cwd(),"src","components"))&&(s=t__default.default.join(process.cwd(),"src","components"));let n=t__default.default.join(s,"FileManagerDemo.tsx");e__default.default.existsSync(n)&&(console.error(`\u274C Error: ${n} already exists.`),process.exit(1)),e__default.default.writeFileSync(n,y("/"),"utf-8"),console.log(`\u2705 Success! Created ${n}`),console.log(""),console.log("You can now import and render <FileManagerDemo /> anywhere in your application."),console.log("Don't forget to configure your Tailwind CSS content to scan the library for styles!"),process.exit(0);}console.log(`
|
|
24
|
+
\u{1F680} Initializing a new application: ${r}
|
|
25
|
+
`),console.log("Which framework would you like to use?"),console.log(" 1) Next.js (App Router, Tailwind v4)"),console.log(" 2) Vite (React, Tailwind v4)"),console.log(" 3) Cancel");let o=await w(`
|
|
26
|
+
Select an option (1-3): `),i=t__default.default.join(process.cwd(),r);e__default.default.existsSync(i)&&(console.error(`
|
|
27
|
+
\u274C Error: Directory "${r}" already exists in ${process.cwd()}.`),console.error(" Please choose a different project name or delete the existing directory first."),f.close(),process.exit(1));try{o==="1"?await F(r,i):o==="2"?await M(r,i):(console.log("Canceled."),process.exit(0));}catch(s){console.error(`
|
|
28
|
+
\u274C Scaffolding failed:`,s),process.exit(1);}process.exit(0);}async function F(o,i){console.log(`
|
|
29
29
|
\u{1F4E6} Creating Next.js application (this may take a minute)...`),child_process.execSync(`npx create-next-app@latest ${o} --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-npm`,{stdio:"inherit"}),console.log(`
|
|
30
|
-
\u{1F4E6} Installing dependencies (@unciatech/file-manager, tailwindcss-animate)...`),child_process.execSync("npm install @unciatech/file-manager tailwindcss-animate",{cwd:
|
|
30
|
+
\u{1F4E6} Installing dependencies (@unciatech/file-manager, tailwindcss-animate)...`),child_process.execSync("npm install @unciatech/file-manager tailwindcss-animate",{cwd:i,stdio:"inherit"});let s=t__default.default.join(i,"src","app","page.tsx");e__default.default.writeFileSync(s,`"use client";
|
|
31
31
|
|
|
32
32
|
import { redirect } from "next/navigation";
|
|
33
33
|
|
|
34
34
|
export default function Home() {
|
|
35
35
|
redirect("/media");
|
|
36
36
|
}
|
|
37
|
-
`);let
|
|
37
|
+
`);let n=t__default.default.join(i,"src","app","media","[[...path]]");e__default.default.mkdirSync(n,{recursive:true}),e__default.default.writeFileSync(t__default.default.join(n,"page.tsx"),`"use client";
|
|
38
38
|
|
|
39
39
|
import { Suspense, useState } from "react";
|
|
40
40
|
import { FileManager, MockProvider } from "@unciatech/file-manager";
|
|
@@ -73,7 +73,7 @@ export default function MediaPage() {
|
|
|
73
73
|
</Suspense>
|
|
74
74
|
);
|
|
75
75
|
}
|
|
76
|
-
`);let d=
|
|
76
|
+
`);let d=t__default.default.join(i,"src","app","modal-demo");e__default.default.mkdirSync(d,{recursive:true}),e__default.default.writeFileSync(t__default.default.join(d,"page.tsx"),`"use client";
|
|
77
77
|
|
|
78
78
|
import { Suspense, useState } from "react";
|
|
79
79
|
import { FileManagerModal, MockProvider } from "@unciatech/file-manager";
|
|
@@ -156,8 +156,8 @@ export default function ModalDemoPage() {
|
|
|
156
156
|
</Suspense>
|
|
157
157
|
);
|
|
158
158
|
}
|
|
159
|
-
`);let
|
|
160
|
-
$1`),
|
|
159
|
+
`);let l=t__default.default.join(i,"src","app","layout.tsx");if(e__default.default.existsSync(l)){let a=e__default.default.readFileSync(l,"utf8");a.includes("@unciatech/file-manager/styles")||(a=a.replace(/^(import type)/m,`import '@unciatech/file-manager/styles';
|
|
160
|
+
$1`),e__default.default.writeFileSync(l,a));}let m=t__default.default.join(i,"src","app","globals.css");e__default.default.writeFileSync(m,`@import "tailwindcss";
|
|
161
161
|
@import "@unciatech/file-manager/styles";
|
|
162
162
|
@import "tw-animate-css";
|
|
163
163
|
|
|
@@ -167,25 +167,27 @@ $1`),t__default.default.writeFileSync(r,n));}let m=i__default.default.join(e,"sr
|
|
|
167
167
|
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
168
168
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
169
169
|
}
|
|
170
|
-
`),
|
|
171
|
-
\u{1F4E6} Creating Vite React application...`),child_process.execSync(`
|
|
172
|
-
\u{1F4E6} Installing dependencies
|
|
170
|
+
`),g(o);}async function M(o,i){if(console.log(`
|
|
171
|
+
\u{1F4E6} Creating Vite React application...`),child_process.execSync(`npx create-vite@latest ${o} --template react-ts`,{stdio:"inherit"}),!e__default.default.existsSync(i))throw new Error("Vite project creation failed.");console.log(`
|
|
172
|
+
\u{1F4E6} Installing dependencies...`),child_process.execSync("npm install",{cwd:i,stdio:"inherit"}),child_process.execSync("npm install tailwindcss @tailwindcss/vite @vitejs/plugin-react react-router-dom @unciatech/file-manager",{cwd:i,stdio:"inherit"});let s=t__default.default.join(i,"src");if(!e__default.default.existsSync(s))throw new Error("src directory not found.");console.log(`
|
|
173
|
+
\u2699\uFE0F Configuring project...`),["App.css","App.tsx"].forEach(v=>{let p=t__default.default.join(s,v);e__default.default.existsSync(p)&&e__default.default.rmSync(p);});let d=t__default.default.join(i,"vite.config.ts");e__default.default.writeFileSync(d,`import { defineConfig } from 'vite'
|
|
173
174
|
import react from '@vitejs/plugin-react'
|
|
174
175
|
import tailwindcss from '@tailwindcss/vite'
|
|
175
176
|
|
|
176
177
|
export default defineConfig({
|
|
177
178
|
plugins: [
|
|
178
179
|
react(),
|
|
179
|
-
tailwindcss()
|
|
180
|
+
tailwindcss()
|
|
180
181
|
],
|
|
181
182
|
})
|
|
182
|
-
`);let
|
|
183
|
+
`);let l=t__default.default.join(s,"index.css");e__default.default.writeFileSync(l,`@import "tailwindcss";
|
|
183
184
|
@import "@unciatech/file-manager/styles";
|
|
185
|
+
|
|
184
186
|
@source "../node_modules/@unciatech/file-manager";
|
|
185
|
-
`);let
|
|
187
|
+
`);let m=t__default.default.join(s,"main.tsx");e__default.default.writeFileSync(m,`import React from 'react'
|
|
186
188
|
import ReactDOM from 'react-dom/client'
|
|
187
189
|
import { BrowserRouter } from 'react-router-dom'
|
|
188
|
-
import App from './App
|
|
190
|
+
import App from './App'
|
|
189
191
|
import './index.css'
|
|
190
192
|
|
|
191
193
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
@@ -195,8 +197,8 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
195
197
|
</BrowserRouter>
|
|
196
198
|
</React.StrictMode>,
|
|
197
199
|
)
|
|
198
|
-
`);let
|
|
199
|
-
import {
|
|
200
|
+
`);let a=t__default.default.join(s,"App.tsx");e__default.default.writeFileSync(a,`import { useState } from 'react'
|
|
201
|
+
import { Routes, Route, Link, useNavigate } from 'react-router-dom'
|
|
200
202
|
import { FileManager, FileManagerModal, MockProvider } from '@unciatech/file-manager'
|
|
201
203
|
import type { FileMetaData } from '@unciatech/file-manager'
|
|
202
204
|
|
|
@@ -207,21 +209,21 @@ function FullPage() {
|
|
|
207
209
|
|
|
208
210
|
return (
|
|
209
211
|
<div className="h-screen w-full flex flex-col">
|
|
210
|
-
<div className="flex gap-4 p-4 border-b
|
|
212
|
+
<div className="flex gap-4 p-4 border-b items-center justify-between">
|
|
211
213
|
<h1 className="text-xl font-bold">Full Page View</h1>
|
|
212
214
|
<Link
|
|
213
215
|
to="/"
|
|
214
|
-
className="px-4 py-2 bg-blue-600 text-white rounded-md
|
|
216
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-md"
|
|
215
217
|
>
|
|
216
|
-
Back
|
|
218
|
+
Back
|
|
217
219
|
</Link>
|
|
218
220
|
</div>
|
|
219
221
|
|
|
220
222
|
<div className="flex-1 relative overflow-hidden">
|
|
221
223
|
<FileManager
|
|
222
224
|
provider={provider}
|
|
223
|
-
basePath="full"
|
|
224
|
-
allowedFileTypes={["images",
|
|
225
|
+
basePath="/full"
|
|
226
|
+
allowedFileTypes={["images","videos","audios","files"]}
|
|
225
227
|
viewMode="grid"
|
|
226
228
|
onNavigate={(url, opts) => navigate(url, { replace: opts?.replace })}
|
|
227
229
|
/>
|
|
@@ -232,70 +234,57 @@ function FullPage() {
|
|
|
232
234
|
|
|
233
235
|
function ModalDemo() {
|
|
234
236
|
const navigate = useNavigate()
|
|
235
|
-
const [
|
|
236
|
-
const [
|
|
237
|
+
const [open, setOpen] = useState(false)
|
|
238
|
+
const [files, setFiles] = useState<FileMetaData[]>([])
|
|
237
239
|
|
|
238
240
|
return (
|
|
239
|
-
<div className="p-10 flex flex-col
|
|
240
|
-
<
|
|
241
|
-
<h1 className="text-3xl font-bold mb-2">File Manager Demo</h1>
|
|
242
|
-
<p className="text-muted-foreground">Select files using the modal or browse the full page view.</p>
|
|
243
|
-
</div>
|
|
241
|
+
<div className="p-10 flex flex-col gap-6 min-h-screen">
|
|
242
|
+
<h1 className="text-3xl font-bold">File Manager Demo</h1>
|
|
244
243
|
|
|
245
244
|
<div className="flex gap-4">
|
|
246
245
|
<button
|
|
247
|
-
onClick={() =>
|
|
248
|
-
className="px-6 py-2
|
|
246
|
+
onClick={() => setOpen(true)}
|
|
247
|
+
className="px-6 py-2 bg-blue-600 text-white rounded-md"
|
|
249
248
|
>
|
|
250
|
-
Open File Picker
|
|
249
|
+
Open File Picker
|
|
251
250
|
</button>
|
|
251
|
+
|
|
252
252
|
<Link
|
|
253
253
|
to="/full"
|
|
254
|
-
className="px-6 py-2
|
|
254
|
+
className="px-6 py-2 bg-zinc-200 rounded-md"
|
|
255
255
|
>
|
|
256
|
-
|
|
256
|
+
Full Page View
|
|
257
257
|
</Link>
|
|
258
258
|
</div>
|
|
259
259
|
|
|
260
|
-
{
|
|
261
|
-
<div className="
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
)}
|
|
272
|
-
</div>
|
|
273
|
-
<div className="w-full text-center">
|
|
274
|
-
<p className="text-sm font-medium truncate w-full" title={file.name}>{file.name}</p>
|
|
275
|
-
<p className="text-xs text-muted-foreground mt-0.5">{(file.size / 1024).toFixed(1)} KB</p>
|
|
276
|
-
</div>
|
|
277
|
-
</div>
|
|
278
|
-
))}
|
|
279
|
-
</div>
|
|
260
|
+
{files.length > 0 && (
|
|
261
|
+
<div className="grid grid-cols-4 gap-4">
|
|
262
|
+
{files.map((file, i) => (
|
|
263
|
+
<div key={i} className="border rounded p-2">
|
|
264
|
+
{file.url && file.mime?.startsWith('image/') ? (
|
|
265
|
+
<img src={file.url} className="w-full h-32 object-cover" />
|
|
266
|
+
) : (
|
|
267
|
+
<div className="text-xs">{file.name}</div>
|
|
268
|
+
)}
|
|
269
|
+
</div>
|
|
270
|
+
))}
|
|
280
271
|
</div>
|
|
281
272
|
)}
|
|
282
273
|
|
|
283
274
|
<FileManagerModal
|
|
284
|
-
open={
|
|
285
|
-
onClose={() =>
|
|
275
|
+
open={open}
|
|
276
|
+
onClose={() => setOpen(false)}
|
|
286
277
|
provider={provider}
|
|
287
278
|
basePath="/"
|
|
288
|
-
allowedFileTypes={["images",
|
|
289
|
-
onFilesSelected={(
|
|
290
|
-
setSelectedFiles(files)
|
|
291
|
-
}}
|
|
279
|
+
allowedFileTypes={["images","videos","audios","files"]}
|
|
280
|
+
onFilesSelected={(f) => setFiles(f)}
|
|
292
281
|
onNavigate={(url, opts) => navigate(url, { replace: opts?.replace })}
|
|
293
282
|
/>
|
|
294
283
|
</div>
|
|
295
284
|
)
|
|
296
285
|
}
|
|
297
286
|
|
|
298
|
-
function App() {
|
|
287
|
+
export default function App() {
|
|
299
288
|
return (
|
|
300
289
|
<Routes>
|
|
301
290
|
<Route path="/" element={<ModalDemo />} />
|
|
@@ -303,10 +292,8 @@ function App() {
|
|
|
303
292
|
</Routes>
|
|
304
293
|
)
|
|
305
294
|
}
|
|
306
|
-
|
|
307
|
-
export default App
|
|
308
|
-
`);let n=i__default.default.join(e,"src","App.css");t__default.default.existsSync(n)&&t__default.default.unlinkSync(n),f(o,"npm run dev");}function f(o,e="npm run dev"){console.log(`
|
|
295
|
+
`),g(o,"npm run dev");}function g(o,i="npm run dev"){console.log(`
|
|
309
296
|
=========================================`),console.log("\u{1F389} Your Media Library application is ready!"),console.log("========================================="),console.log(`
|
|
310
|
-
Next steps:`),console.log(` cd ${o}`),console.log(` ${
|
|
297
|
+
Next steps:`),console.log(` cd ${o}`),console.log(` ${i}`),console.log(`
|
|
311
298
|
Enjoy building! \u{1F5C2}\uFE0F
|
|
312
|
-
`);}
|
|
299
|
+
`);}b();
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import e from'fs';import t from'path';import {execSync}from'child_process';import x from'readline';var u=process.argv.slice(2),h=u[0],r=u[1],f=x.createInterface({input:process.stdin,output:process.stdout}),w=o=>new Promise(i=>f.question(o,i)),y=(o="/media")=>`"use client";
|
|
3
3
|
|
|
4
4
|
import React, { Suspense } from "react";
|
|
5
5
|
import { FileManager, MockProvider } from "@unciatech/file-manager";
|
|
@@ -20,21 +20,21 @@ export default function FileManagerDemo() {
|
|
|
20
20
|
</div>
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
|
-
`;async function
|
|
24
|
-
\u{1F680} Initializing a new application: ${
|
|
25
|
-
`),console.log("Which framework would you like to use?"),console.log(" 1) Next.js (App Router, Tailwind v4)"),console.log(" 2) Vite (React, Tailwind v4)"),console.log(" 3) Cancel");let o=await
|
|
26
|
-
Select an option (1-3): `),
|
|
27
|
-
\u274C Error: Directory "${
|
|
28
|
-
\u274C Scaffolding failed:`,s),process.exit(1);}process.exit(0);}async function
|
|
23
|
+
`;async function b(){if(h!=="init"&&(console.log("Usage: npx @unciatech/file-manager init [project-name]"),process.exit(0)),!r){console.log("\u{1F680} Generating <FileManagerDemo /> component in the current project...");let s=process.cwd();e.existsSync(t.join(process.cwd(),"components"))?s=t.join(process.cwd(),"components"):e.existsSync(t.join(process.cwd(),"src","components"))&&(s=t.join(process.cwd(),"src","components"));let n=t.join(s,"FileManagerDemo.tsx");e.existsSync(n)&&(console.error(`\u274C Error: ${n} already exists.`),process.exit(1)),e.writeFileSync(n,y("/"),"utf-8"),console.log(`\u2705 Success! Created ${n}`),console.log(""),console.log("You can now import and render <FileManagerDemo /> anywhere in your application."),console.log("Don't forget to configure your Tailwind CSS content to scan the library for styles!"),process.exit(0);}console.log(`
|
|
24
|
+
\u{1F680} Initializing a new application: ${r}
|
|
25
|
+
`),console.log("Which framework would you like to use?"),console.log(" 1) Next.js (App Router, Tailwind v4)"),console.log(" 2) Vite (React, Tailwind v4)"),console.log(" 3) Cancel");let o=await w(`
|
|
26
|
+
Select an option (1-3): `),i=t.join(process.cwd(),r);e.existsSync(i)&&(console.error(`
|
|
27
|
+
\u274C Error: Directory "${r}" already exists in ${process.cwd()}.`),console.error(" Please choose a different project name or delete the existing directory first."),f.close(),process.exit(1));try{o==="1"?await F(r,i):o==="2"?await M(r,i):(console.log("Canceled."),process.exit(0));}catch(s){console.error(`
|
|
28
|
+
\u274C Scaffolding failed:`,s),process.exit(1);}process.exit(0);}async function F(o,i){console.log(`
|
|
29
29
|
\u{1F4E6} Creating Next.js application (this may take a minute)...`),execSync(`npx create-next-app@latest ${o} --ts --tailwind --eslint --app --src-dir --import-alias "@/*" --use-npm`,{stdio:"inherit"}),console.log(`
|
|
30
|
-
\u{1F4E6} Installing dependencies (@unciatech/file-manager, tailwindcss-animate)...`),execSync("npm install @unciatech/file-manager tailwindcss-animate",{cwd:
|
|
30
|
+
\u{1F4E6} Installing dependencies (@unciatech/file-manager, tailwindcss-animate)...`),execSync("npm install @unciatech/file-manager tailwindcss-animate",{cwd:i,stdio:"inherit"});let s=t.join(i,"src","app","page.tsx");e.writeFileSync(s,`"use client";
|
|
31
31
|
|
|
32
32
|
import { redirect } from "next/navigation";
|
|
33
33
|
|
|
34
34
|
export default function Home() {
|
|
35
35
|
redirect("/media");
|
|
36
36
|
}
|
|
37
|
-
`);let
|
|
37
|
+
`);let n=t.join(i,"src","app","media","[[...path]]");e.mkdirSync(n,{recursive:true}),e.writeFileSync(t.join(n,"page.tsx"),`"use client";
|
|
38
38
|
|
|
39
39
|
import { Suspense, useState } from "react";
|
|
40
40
|
import { FileManager, MockProvider } from "@unciatech/file-manager";
|
|
@@ -73,7 +73,7 @@ export default function MediaPage() {
|
|
|
73
73
|
</Suspense>
|
|
74
74
|
);
|
|
75
75
|
}
|
|
76
|
-
`);let d=
|
|
76
|
+
`);let d=t.join(i,"src","app","modal-demo");e.mkdirSync(d,{recursive:true}),e.writeFileSync(t.join(d,"page.tsx"),`"use client";
|
|
77
77
|
|
|
78
78
|
import { Suspense, useState } from "react";
|
|
79
79
|
import { FileManagerModal, MockProvider } from "@unciatech/file-manager";
|
|
@@ -156,8 +156,8 @@ export default function ModalDemoPage() {
|
|
|
156
156
|
</Suspense>
|
|
157
157
|
);
|
|
158
158
|
}
|
|
159
|
-
`);let
|
|
160
|
-
$1`),
|
|
159
|
+
`);let l=t.join(i,"src","app","layout.tsx");if(e.existsSync(l)){let a=e.readFileSync(l,"utf8");a.includes("@unciatech/file-manager/styles")||(a=a.replace(/^(import type)/m,`import '@unciatech/file-manager/styles';
|
|
160
|
+
$1`),e.writeFileSync(l,a));}let m=t.join(i,"src","app","globals.css");e.writeFileSync(m,`@import "tailwindcss";
|
|
161
161
|
@import "@unciatech/file-manager/styles";
|
|
162
162
|
@import "tw-animate-css";
|
|
163
163
|
|
|
@@ -167,25 +167,27 @@ $1`),t.writeFileSync(r,n));}let m=i.join(e,"src","app","globals.css");t.writeFil
|
|
|
167
167
|
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
168
168
|
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
169
169
|
}
|
|
170
|
-
`),
|
|
171
|
-
\u{1F4E6} Creating Vite React application...`),execSync(`
|
|
172
|
-
\u{1F4E6} Installing dependencies
|
|
170
|
+
`),g(o);}async function M(o,i){if(console.log(`
|
|
171
|
+
\u{1F4E6} Creating Vite React application...`),execSync(`npx create-vite@latest ${o} --template react-ts`,{stdio:"inherit"}),!e.existsSync(i))throw new Error("Vite project creation failed.");console.log(`
|
|
172
|
+
\u{1F4E6} Installing dependencies...`),execSync("npm install",{cwd:i,stdio:"inherit"}),execSync("npm install tailwindcss @tailwindcss/vite @vitejs/plugin-react react-router-dom @unciatech/file-manager",{cwd:i,stdio:"inherit"});let s=t.join(i,"src");if(!e.existsSync(s))throw new Error("src directory not found.");console.log(`
|
|
173
|
+
\u2699\uFE0F Configuring project...`),["App.css","App.tsx"].forEach(v=>{let p=t.join(s,v);e.existsSync(p)&&e.rmSync(p);});let d=t.join(i,"vite.config.ts");e.writeFileSync(d,`import { defineConfig } from 'vite'
|
|
173
174
|
import react from '@vitejs/plugin-react'
|
|
174
175
|
import tailwindcss from '@tailwindcss/vite'
|
|
175
176
|
|
|
176
177
|
export default defineConfig({
|
|
177
178
|
plugins: [
|
|
178
179
|
react(),
|
|
179
|
-
tailwindcss()
|
|
180
|
+
tailwindcss()
|
|
180
181
|
],
|
|
181
182
|
})
|
|
182
|
-
`);let
|
|
183
|
+
`);let l=t.join(s,"index.css");e.writeFileSync(l,`@import "tailwindcss";
|
|
183
184
|
@import "@unciatech/file-manager/styles";
|
|
185
|
+
|
|
184
186
|
@source "../node_modules/@unciatech/file-manager";
|
|
185
|
-
`);let
|
|
187
|
+
`);let m=t.join(s,"main.tsx");e.writeFileSync(m,`import React from 'react'
|
|
186
188
|
import ReactDOM from 'react-dom/client'
|
|
187
189
|
import { BrowserRouter } from 'react-router-dom'
|
|
188
|
-
import App from './App
|
|
190
|
+
import App from './App'
|
|
189
191
|
import './index.css'
|
|
190
192
|
|
|
191
193
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
@@ -195,8 +197,8 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
195
197
|
</BrowserRouter>
|
|
196
198
|
</React.StrictMode>,
|
|
197
199
|
)
|
|
198
|
-
`);let
|
|
199
|
-
import {
|
|
200
|
+
`);let a=t.join(s,"App.tsx");e.writeFileSync(a,`import { useState } from 'react'
|
|
201
|
+
import { Routes, Route, Link, useNavigate } from 'react-router-dom'
|
|
200
202
|
import { FileManager, FileManagerModal, MockProvider } from '@unciatech/file-manager'
|
|
201
203
|
import type { FileMetaData } from '@unciatech/file-manager'
|
|
202
204
|
|
|
@@ -207,21 +209,21 @@ function FullPage() {
|
|
|
207
209
|
|
|
208
210
|
return (
|
|
209
211
|
<div className="h-screen w-full flex flex-col">
|
|
210
|
-
<div className="flex gap-4 p-4 border-b
|
|
212
|
+
<div className="flex gap-4 p-4 border-b items-center justify-between">
|
|
211
213
|
<h1 className="text-xl font-bold">Full Page View</h1>
|
|
212
214
|
<Link
|
|
213
215
|
to="/"
|
|
214
|
-
className="px-4 py-2 bg-blue-600 text-white rounded-md
|
|
216
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-md"
|
|
215
217
|
>
|
|
216
|
-
Back
|
|
218
|
+
Back
|
|
217
219
|
</Link>
|
|
218
220
|
</div>
|
|
219
221
|
|
|
220
222
|
<div className="flex-1 relative overflow-hidden">
|
|
221
223
|
<FileManager
|
|
222
224
|
provider={provider}
|
|
223
|
-
basePath="full"
|
|
224
|
-
allowedFileTypes={["images",
|
|
225
|
+
basePath="/full"
|
|
226
|
+
allowedFileTypes={["images","videos","audios","files"]}
|
|
225
227
|
viewMode="grid"
|
|
226
228
|
onNavigate={(url, opts) => navigate(url, { replace: opts?.replace })}
|
|
227
229
|
/>
|
|
@@ -232,70 +234,57 @@ function FullPage() {
|
|
|
232
234
|
|
|
233
235
|
function ModalDemo() {
|
|
234
236
|
const navigate = useNavigate()
|
|
235
|
-
const [
|
|
236
|
-
const [
|
|
237
|
+
const [open, setOpen] = useState(false)
|
|
238
|
+
const [files, setFiles] = useState<FileMetaData[]>([])
|
|
237
239
|
|
|
238
240
|
return (
|
|
239
|
-
<div className="p-10 flex flex-col
|
|
240
|
-
<
|
|
241
|
-
<h1 className="text-3xl font-bold mb-2">File Manager Demo</h1>
|
|
242
|
-
<p className="text-muted-foreground">Select files using the modal or browse the full page view.</p>
|
|
243
|
-
</div>
|
|
241
|
+
<div className="p-10 flex flex-col gap-6 min-h-screen">
|
|
242
|
+
<h1 className="text-3xl font-bold">File Manager Demo</h1>
|
|
244
243
|
|
|
245
244
|
<div className="flex gap-4">
|
|
246
245
|
<button
|
|
247
|
-
onClick={() =>
|
|
248
|
-
className="px-6 py-2
|
|
246
|
+
onClick={() => setOpen(true)}
|
|
247
|
+
className="px-6 py-2 bg-blue-600 text-white rounded-md"
|
|
249
248
|
>
|
|
250
|
-
Open File Picker
|
|
249
|
+
Open File Picker
|
|
251
250
|
</button>
|
|
251
|
+
|
|
252
252
|
<Link
|
|
253
253
|
to="/full"
|
|
254
|
-
className="px-6 py-2
|
|
254
|
+
className="px-6 py-2 bg-zinc-200 rounded-md"
|
|
255
255
|
>
|
|
256
|
-
|
|
256
|
+
Full Page View
|
|
257
257
|
</Link>
|
|
258
258
|
</div>
|
|
259
259
|
|
|
260
|
-
{
|
|
261
|
-
<div className="
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
)}
|
|
272
|
-
</div>
|
|
273
|
-
<div className="w-full text-center">
|
|
274
|
-
<p className="text-sm font-medium truncate w-full" title={file.name}>{file.name}</p>
|
|
275
|
-
<p className="text-xs text-muted-foreground mt-0.5">{(file.size / 1024).toFixed(1)} KB</p>
|
|
276
|
-
</div>
|
|
277
|
-
</div>
|
|
278
|
-
))}
|
|
279
|
-
</div>
|
|
260
|
+
{files.length > 0 && (
|
|
261
|
+
<div className="grid grid-cols-4 gap-4">
|
|
262
|
+
{files.map((file, i) => (
|
|
263
|
+
<div key={i} className="border rounded p-2">
|
|
264
|
+
{file.url && file.mime?.startsWith('image/') ? (
|
|
265
|
+
<img src={file.url} className="w-full h-32 object-cover" />
|
|
266
|
+
) : (
|
|
267
|
+
<div className="text-xs">{file.name}</div>
|
|
268
|
+
)}
|
|
269
|
+
</div>
|
|
270
|
+
))}
|
|
280
271
|
</div>
|
|
281
272
|
)}
|
|
282
273
|
|
|
283
274
|
<FileManagerModal
|
|
284
|
-
open={
|
|
285
|
-
onClose={() =>
|
|
275
|
+
open={open}
|
|
276
|
+
onClose={() => setOpen(false)}
|
|
286
277
|
provider={provider}
|
|
287
278
|
basePath="/"
|
|
288
|
-
allowedFileTypes={["images",
|
|
289
|
-
onFilesSelected={(
|
|
290
|
-
setSelectedFiles(files)
|
|
291
|
-
}}
|
|
279
|
+
allowedFileTypes={["images","videos","audios","files"]}
|
|
280
|
+
onFilesSelected={(f) => setFiles(f)}
|
|
292
281
|
onNavigate={(url, opts) => navigate(url, { replace: opts?.replace })}
|
|
293
282
|
/>
|
|
294
283
|
</div>
|
|
295
284
|
)
|
|
296
285
|
}
|
|
297
286
|
|
|
298
|
-
function App() {
|
|
287
|
+
export default function App() {
|
|
299
288
|
return (
|
|
300
289
|
<Routes>
|
|
301
290
|
<Route path="/" element={<ModalDemo />} />
|
|
@@ -303,10 +292,8 @@ function App() {
|
|
|
303
292
|
</Routes>
|
|
304
293
|
)
|
|
305
294
|
}
|
|
306
|
-
|
|
307
|
-
export default App
|
|
308
|
-
`);let n=i.join(e,"src","App.css");t.existsSync(n)&&t.unlinkSync(n),f(o,"npm run dev");}function f(o,e="npm run dev"){console.log(`
|
|
295
|
+
`),g(o,"npm run dev");}function g(o,i="npm run dev"){console.log(`
|
|
309
296
|
=========================================`),console.log("\u{1F389} Your Media Library application is ready!"),console.log("========================================="),console.log(`
|
|
310
|
-
Next steps:`),console.log(` cd ${o}`),console.log(` ${
|
|
297
|
+
Next steps:`),console.log(` cd ${o}`),console.log(` ${i}`),console.log(`
|
|
311
298
|
Enjoy building! \u{1F5C2}\uFE0F
|
|
312
|
-
`);}
|
|
299
|
+
`);}b();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unciatech/file-manager",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.40",
|
|
4
4
|
"description": "Modern file manager component for React applications",
|
|
5
5
|
"author": "Avi",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
"main": "./dist/index.cjs",
|
|
22
22
|
"module": "./dist/index.js",
|
|
23
23
|
"types": "./dist/index.d.ts",
|
|
24
|
-
"bin":
|
|
24
|
+
"bin": {
|
|
25
|
+
"file-manager": "./dist/cli.cjs"
|
|
26
|
+
},
|
|
25
27
|
"exports": {
|
|
26
28
|
".": {
|
|
27
29
|
"types": "./dist/index.d.ts",
|
|
@@ -41,7 +43,6 @@
|
|
|
41
43
|
},
|
|
42
44
|
"files": [
|
|
43
45
|
"dist",
|
|
44
|
-
"bin",
|
|
45
46
|
"README.md"
|
|
46
47
|
],
|
|
47
48
|
"sideEffects": [
|
package/bin/file-manager.js
DELETED