@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 CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var t=require('fs'),i=require('path'),child_process=require('child_process'),g=require('readline');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var t__default=/*#__PURE__*/_interopDefault(t);var i__default=/*#__PURE__*/_interopDefault(i);var g__default=/*#__PURE__*/_interopDefault(g);var p=process.argv.slice(2),v=p[0],l=p[1],u=g__default.default.createInterface({input:process.stdin,output:process.stdout}),x=o=>new Promise(e=>u.question(o,e)),h=(o="/media")=>`"use client";
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 w(){if(v!=="init"&&(console.log("Usage: npx @unciatech/file-manager init [project-name]"),process.exit(0)),!l){console.log("\u{1F680} Generating <FileManagerDemo /> component in the current project...");let s=process.cwd();t__default.default.existsSync(i__default.default.join(process.cwd(),"components"))?s=i__default.default.join(process.cwd(),"components"):t__default.default.existsSync(i__default.default.join(process.cwd(),"src","components"))&&(s=i__default.default.join(process.cwd(),"src","components"));let a=i__default.default.join(s,"FileManagerDemo.tsx");t__default.default.existsSync(a)&&(console.error(`\u274C Error: ${a} already exists.`),process.exit(1)),t__default.default.writeFileSync(a,h("/"),"utf-8"),console.log(`\u2705 Success! Created ${a}`),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: ${l}
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 x(`
26
- Select an option (1-3): `),e=i__default.default.join(process.cwd(),l);t__default.default.existsSync(e)&&(console.error(`
27
- \u274C Error: Directory "${l}" already exists in ${process.cwd()}.`),console.error(" Please choose a different project name or delete the existing directory first."),u.close(),process.exit(1));try{o==="1"?await b(l,e):o==="2"?await y(l,e):(console.log("Canceled."),process.exit(0));}catch(s){console.error(`
28
- \u274C Scaffolding failed:`,s),process.exit(1);}process.exit(0);}async function b(o,e){console.log(`
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:e,stdio:"inherit"});let s=i__default.default.join(e,"src","app","page.tsx");t__default.default.writeFileSync(s,`"use client";
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 a=i__default.default.join(e,"src","app","media","[[...path]]");t__default.default.mkdirSync(a,{recursive:true}),t__default.default.writeFileSync(i__default.default.join(a,"page.tsx"),`"use client";
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=i__default.default.join(e,"src","app","modal-demo");t__default.default.mkdirSync(d,{recursive:true}),t__default.default.writeFileSync(i__default.default.join(d,"page.tsx"),`"use client";
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 r=i__default.default.join(e,"src","app","layout.tsx");if(t__default.default.existsSync(r)){let n=t__default.default.readFileSync(r,"utf8");n.includes("@unciatech/file-manager/styles")||(n=n.replace(/^(import type)/m,`import '@unciatech/file-manager/styles';
160
- $1`),t__default.default.writeFileSync(r,n));}let m=i__default.default.join(e,"src","app","globals.css");t__default.default.writeFileSync(m,`@import "tailwindcss";
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
- `),f(o);}async function y(o,e){console.log(`
171
- \u{1F4E6} Creating Vite React application...`),child_process.execSync(`npm create vite@latest ${o} -- --template react-ts`,{stdio:"inherit"}),console.log(`
172
- \u{1F4E6} Installing dependencies (Tailwind + File Manager + React Router)...`),child_process.execSync("npm install",{cwd:e,stdio:"inherit"}),child_process.execSync("npm install tailwindcss @tailwindcss/vite @unciatech/file-manager react-router-dom",{cwd:e,stdio:"inherit"});let s=i__default.default.join(e,"vite.config.ts");t__default.default.writeFileSync(s,`import { defineConfig } from 'vite'
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 d=i__default.default.join(e,"src","index.css");t__default.default.writeFileSync(d,`@import "tailwindcss";
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 r=i__default.default.join(e,"src","main.tsx");t__default.default.writeFileSync(r,`import React from 'react'
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.tsx'
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 m=i__default.default.join(e,"src","App.tsx");t__default.default.writeFileSync(m,`import { useState } from 'react'
199
- import { useNavigate, Routes, Route, Link } from 'react-router-dom'
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 border-border items-center justify-between">
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 hover:bg-blue-700 cursor-pointer text-sm font-medium"
216
+ className="px-4 py-2 bg-blue-600 text-white rounded-md"
215
217
  >
216
- Back to Modal Demo
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", "videos", "audios", "files"]}
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 [isModalOpen, setIsModalOpen] = useState(false)
236
- const [selectedFiles, setSelectedFiles] = useState<FileMetaData[]>([])
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 items-start gap-6 min-h-screen w-full bg-background text-foreground">
240
- <div>
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={() => setIsModalOpen(true)}
248
- className="px-6 py-2.5 bg-blue-600 text-white rounded-md hover:bg-blue-700 cursor-pointer text-sm font-medium shadow-sm transition-colors"
246
+ onClick={() => setOpen(true)}
247
+ className="px-6 py-2 bg-blue-600 text-white rounded-md"
249
248
  >
250
- Open File Picker Modal
249
+ Open File Picker
251
250
  </button>
251
+
252
252
  <Link
253
253
  to="/full"
254
- className="px-6 py-2.5 bg-zinc-100 dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 rounded-md hover:bg-zinc-200 dark:hover:bg-zinc-700 cursor-pointer text-sm font-medium transition-colors"
254
+ className="px-6 py-2 bg-zinc-200 rounded-md"
255
255
  >
256
- Go to Full Page View
256
+ Full Page View
257
257
  </Link>
258
258
  </div>
259
259
 
260
- {selectedFiles.length > 0 && (
261
- <div className="w-full mt-8">
262
- <h2 className="text-xl font-semibold mb-4 border-b pb-2">Selected Files ({selectedFiles.length})</h2>
263
- <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
264
- {selectedFiles.map((file, idx) => (
265
- <div key={idx} className="border border-border rounded-lg p-3 flex flex-col items-center gap-3 bg-card shadow-sm">
266
- <div className="w-full aspect-square bg-muted rounded-md overflow-hidden flex items-center justify-center relative">
267
- {file.url && file.mime?.startsWith('image/') ? (
268
- <img src={file.url} alt={file.name} className="w-full h-full object-cover" />
269
- ) : (
270
- <span className="text-muted-foreground font-mono text-xs p-2 overflow-hidden text-ellipsis">{file.ext?.toUpperCase() || 'FILE'}</span>
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={isModalOpen}
285
- onClose={() => setIsModalOpen(false)}
275
+ open={open}
276
+ onClose={() => setOpen(false)}
286
277
  provider={provider}
287
278
  basePath="/"
288
- allowedFileTypes={["images", "videos", "audios", "files"]}
289
- onFilesSelected={(files: FileMetaData[]) => {
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(` ${e}`),console.log(`
297
+ Next steps:`),console.log(` cd ${o}`),console.log(` ${i}`),console.log(`
311
298
  Enjoy building! \u{1F5C2}\uFE0F
312
- `);}w();
299
+ `);}b();
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import t from'fs';import i from'path';import {execSync}from'child_process';import g from'readline';var p=process.argv.slice(2),v=p[0],l=p[1],u=g.createInterface({input:process.stdin,output:process.stdout}),x=o=>new Promise(e=>u.question(o,e)),h=(o="/media")=>`"use client";
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 w(){if(v!=="init"&&(console.log("Usage: npx @unciatech/file-manager init [project-name]"),process.exit(0)),!l){console.log("\u{1F680} Generating <FileManagerDemo /> component in the current project...");let s=process.cwd();t.existsSync(i.join(process.cwd(),"components"))?s=i.join(process.cwd(),"components"):t.existsSync(i.join(process.cwd(),"src","components"))&&(s=i.join(process.cwd(),"src","components"));let a=i.join(s,"FileManagerDemo.tsx");t.existsSync(a)&&(console.error(`\u274C Error: ${a} already exists.`),process.exit(1)),t.writeFileSync(a,h("/"),"utf-8"),console.log(`\u2705 Success! Created ${a}`),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: ${l}
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 x(`
26
- Select an option (1-3): `),e=i.join(process.cwd(),l);t.existsSync(e)&&(console.error(`
27
- \u274C Error: Directory "${l}" already exists in ${process.cwd()}.`),console.error(" Please choose a different project name or delete the existing directory first."),u.close(),process.exit(1));try{o==="1"?await b(l,e):o==="2"?await y(l,e):(console.log("Canceled."),process.exit(0));}catch(s){console.error(`
28
- \u274C Scaffolding failed:`,s),process.exit(1);}process.exit(0);}async function b(o,e){console.log(`
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:e,stdio:"inherit"});let s=i.join(e,"src","app","page.tsx");t.writeFileSync(s,`"use client";
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 a=i.join(e,"src","app","media","[[...path]]");t.mkdirSync(a,{recursive:true}),t.writeFileSync(i.join(a,"page.tsx"),`"use client";
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=i.join(e,"src","app","modal-demo");t.mkdirSync(d,{recursive:true}),t.writeFileSync(i.join(d,"page.tsx"),`"use client";
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 r=i.join(e,"src","app","layout.tsx");if(t.existsSync(r)){let n=t.readFileSync(r,"utf8");n.includes("@unciatech/file-manager/styles")||(n=n.replace(/^(import type)/m,`import '@unciatech/file-manager/styles';
160
- $1`),t.writeFileSync(r,n));}let m=i.join(e,"src","app","globals.css");t.writeFileSync(m,`@import "tailwindcss";
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
- `),f(o);}async function y(o,e){console.log(`
171
- \u{1F4E6} Creating Vite React application...`),execSync(`npm create vite@latest ${o} -- --template react-ts`,{stdio:"inherit"}),console.log(`
172
- \u{1F4E6} Installing dependencies (Tailwind + File Manager + React Router)...`),execSync("npm install",{cwd:e,stdio:"inherit"}),execSync("npm install tailwindcss @tailwindcss/vite @unciatech/file-manager react-router-dom",{cwd:e,stdio:"inherit"});let s=i.join(e,"vite.config.ts");t.writeFileSync(s,`import { defineConfig } from 'vite'
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 d=i.join(e,"src","index.css");t.writeFileSync(d,`@import "tailwindcss";
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 r=i.join(e,"src","main.tsx");t.writeFileSync(r,`import React from 'react'
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.tsx'
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 m=i.join(e,"src","App.tsx");t.writeFileSync(m,`import { useState } from 'react'
199
- import { useNavigate, Routes, Route, Link } from 'react-router-dom'
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 border-border items-center justify-between">
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 hover:bg-blue-700 cursor-pointer text-sm font-medium"
216
+ className="px-4 py-2 bg-blue-600 text-white rounded-md"
215
217
  >
216
- Back to Modal Demo
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", "videos", "audios", "files"]}
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 [isModalOpen, setIsModalOpen] = useState(false)
236
- const [selectedFiles, setSelectedFiles] = useState<FileMetaData[]>([])
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 items-start gap-6 min-h-screen w-full bg-background text-foreground">
240
- <div>
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={() => setIsModalOpen(true)}
248
- className="px-6 py-2.5 bg-blue-600 text-white rounded-md hover:bg-blue-700 cursor-pointer text-sm font-medium shadow-sm transition-colors"
246
+ onClick={() => setOpen(true)}
247
+ className="px-6 py-2 bg-blue-600 text-white rounded-md"
249
248
  >
250
- Open File Picker Modal
249
+ Open File Picker
251
250
  </button>
251
+
252
252
  <Link
253
253
  to="/full"
254
- className="px-6 py-2.5 bg-zinc-100 dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 rounded-md hover:bg-zinc-200 dark:hover:bg-zinc-700 cursor-pointer text-sm font-medium transition-colors"
254
+ className="px-6 py-2 bg-zinc-200 rounded-md"
255
255
  >
256
- Go to Full Page View
256
+ Full Page View
257
257
  </Link>
258
258
  </div>
259
259
 
260
- {selectedFiles.length > 0 && (
261
- <div className="w-full mt-8">
262
- <h2 className="text-xl font-semibold mb-4 border-b pb-2">Selected Files ({selectedFiles.length})</h2>
263
- <div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 gap-4">
264
- {selectedFiles.map((file, idx) => (
265
- <div key={idx} className="border border-border rounded-lg p-3 flex flex-col items-center gap-3 bg-card shadow-sm">
266
- <div className="w-full aspect-square bg-muted rounded-md overflow-hidden flex items-center justify-center relative">
267
- {file.url && file.mime?.startsWith('image/') ? (
268
- <img src={file.url} alt={file.name} className="w-full h-full object-cover" />
269
- ) : (
270
- <span className="text-muted-foreground font-mono text-xs p-2 overflow-hidden text-ellipsis">{file.ext?.toUpperCase() || 'FILE'}</span>
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={isModalOpen}
285
- onClose={() => setIsModalOpen(false)}
275
+ open={open}
276
+ onClose={() => setOpen(false)}
286
277
  provider={provider}
287
278
  basePath="/"
288
- allowedFileTypes={["images", "videos", "audios", "files"]}
289
- onFilesSelected={(files: FileMetaData[]) => {
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(` ${e}`),console.log(`
297
+ Next steps:`),console.log(` cd ${o}`),console.log(` ${i}`),console.log(`
311
298
  Enjoy building! \u{1F5C2}\uFE0F
312
- `);}w();
299
+ `);}b();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unciatech/file-manager",
3
- "version": "0.0.39",
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": "bin/file-manager.js",
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": [
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import('../dist/cli.js');