@muhgholy/next-drive 0.1.0
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 +230 -0
- package/dist/client/index.css +48 -0
- package/dist/client/index.css.map +1 -0
- package/dist/client/index.d.ts +128 -0
- package/dist/client/index.js +2863 -0
- package/dist/client/index.js.map +1 -0
- package/dist/index-DE7-rwJm.d.ts +87 -0
- package/dist/server/index.d.ts +115 -0
- package/dist/server/index.js +1413 -0
- package/dist/server/index.js.map +1 -0
- package/package.json +89 -0
package/README.md
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# @muhgholy/next-drive
|
|
2
|
+
|
|
3
|
+
Robust file storage and management solution for Next.js applications, featuring a responsive UI, advanced search, trash management, and secure file handling.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **File Management**: Upload, rename, move, and organize files and folders.
|
|
8
|
+
- **Advanced Search**: Search both active files and the trash bin with real-time filtering.
|
|
9
|
+
- **Trash System**: specialized trash view with soft delete, restore, and empty trash capabilities.
|
|
10
|
+
- **Responsive UI**: optimized layouts for both desktop (single toolbar) and mobile (search-focused header).
|
|
11
|
+
- **Video Support**: Auto-generates thumbnails for video files (requires FFmpeg).
|
|
12
|
+
- **Security**: Signed URLs for secure file access and configurable upload limits.
|
|
13
|
+
- **View Modes**: Toggle between Grid and List views with custom sorting and grouping.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @muhgholy/next-drive
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Peer Dependencies:**
|
|
22
|
+
|
|
23
|
+
- Next.js >= 14
|
|
24
|
+
- React >= 18
|
|
25
|
+
- Mongoose >= 7
|
|
26
|
+
|
|
27
|
+
**System Requirements:**
|
|
28
|
+
|
|
29
|
+
- **FFmpeg**: Required for generating thumbnails from video files.
|
|
30
|
+
- MacOS: `brew install ffmpeg`
|
|
31
|
+
- Ubuntu: `sudo apt install ffmpeg`
|
|
32
|
+
- Windows: Download from official site and add to PATH.
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
### 1. Configure Server
|
|
37
|
+
|
|
38
|
+
Create a configuration file (e.g., `lib/drive.ts`) to set up storage paths, database connection, and security rules.
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// lib/drive.ts
|
|
42
|
+
import { driveConfiguration } from "@muhgholy/next-drive/server";
|
|
43
|
+
import type { TDriveConfigInformation } from "@muhgholy/next-drive/server";
|
|
44
|
+
|
|
45
|
+
export const drive = driveConfiguration({
|
|
46
|
+
database: "MONGOOSE",
|
|
47
|
+
storage: { path: "/var/data/drive" },
|
|
48
|
+
security: {
|
|
49
|
+
maxUploadSize: 50 * 1024 * 1024, // 50MB
|
|
50
|
+
allowedMimeTypes: ["image/*", "video/*", "application/pdf"],
|
|
51
|
+
signedUrls: {
|
|
52
|
+
enabled: true,
|
|
53
|
+
secret: process.env.DRIVE_SECRET!,
|
|
54
|
+
expiresIn: 3600, // 1 hour
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
image: {
|
|
58
|
+
formats: ["webp", "jpeg", "png"],
|
|
59
|
+
qualities: ["ultralow", "low", "medium", "high", "normal"],
|
|
60
|
+
},
|
|
61
|
+
information: async (req): Promise<TDriveConfigInformation> => {
|
|
62
|
+
// Implement your auth verification here
|
|
63
|
+
const auth = await verifyAuth(req);
|
|
64
|
+
return {
|
|
65
|
+
key: auth ? { userId: auth.userId } : null,
|
|
66
|
+
storage: { quotaInBytes: 1024 * 1024 * 1024 }, // 1GB limit
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 2. Create API Route
|
|
73
|
+
|
|
74
|
+
Set up the API route handler that `next-drive` will use to communicate with the client.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// pages/api/drive.ts (Pages Router)
|
|
78
|
+
// or app/api/drive/route.ts (App Router)
|
|
79
|
+
|
|
80
|
+
import { drive } from "@/lib/drive";
|
|
81
|
+
import { driveAPIHandler } from "@muhgholy/next-drive/server";
|
|
82
|
+
|
|
83
|
+
export default function handler(req, res) {
|
|
84
|
+
return driveAPIHandler(drive, req, res);
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Add Provider
|
|
89
|
+
|
|
90
|
+
Wrap your application or the specific route with `DriveProvider`.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// app/layout.tsx
|
|
94
|
+
import { DriveProvider } from "@muhgholy/next-drive/client";
|
|
95
|
+
|
|
96
|
+
export default function RootLayout({ children }) {
|
|
97
|
+
return <DriveProvider apiEndpoint="/api/drive">{children}</DriveProvider>;
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 4. Implement UI Components
|
|
102
|
+
|
|
103
|
+
You can use the built-in `DriveExplorer` for a full file manager experience or `DriveFileChooser` for form inputs.
|
|
104
|
+
|
|
105
|
+
**Full File Explorer:**
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
import { DriveExplorer } from "@muhgholy/next-drive/client";
|
|
109
|
+
|
|
110
|
+
export default function DrivePage() {
|
|
111
|
+
return <DriveExplorer />;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**File Picker:**
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { DriveFileChooser } from "@muhgholy/next-drive/client";
|
|
119
|
+
import type { TDriveFile } from "@muhgholy/next-drive/client";
|
|
120
|
+
|
|
121
|
+
function MyForm() {
|
|
122
|
+
const [file, setFile] = useState<TDriveFile | null>(null);
|
|
123
|
+
|
|
124
|
+
return <DriveFileChooser value={file} onChange={setFile} accept="image/*" />;
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Key Capabilities
|
|
129
|
+
|
|
130
|
+
### Server-Side File Access
|
|
131
|
+
|
|
132
|
+
**Get File URL:**
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { driveGetUrl } from "@muhgholy/next-drive/server";
|
|
136
|
+
|
|
137
|
+
// Generate a secure URL
|
|
138
|
+
const url = driveGetUrl(fileId);
|
|
139
|
+
// Returns: /api/drive?action=serve&id={fileId}&token={signedToken}
|
|
140
|
+
|
|
141
|
+
// With custom expiry (in seconds)
|
|
142
|
+
const url = driveGetUrl(fileId, { expiry: 7200 }); // 2 hours
|
|
143
|
+
|
|
144
|
+
// With specific expiry date
|
|
145
|
+
const url = driveGetUrl(fileId, { expiry: new Date("2025-12-31") });
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Read File Stream:**
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
import { driveReadFile } from "@muhgholy/next-drive/server";
|
|
152
|
+
|
|
153
|
+
// Using file ID
|
|
154
|
+
const { stream, mime, size } = await driveReadFile(fileId);
|
|
155
|
+
stream.pipe(response);
|
|
156
|
+
|
|
157
|
+
// Using database document
|
|
158
|
+
const drive = await Drive.findById(fileId);
|
|
159
|
+
const { stream, mime, size } = await driveReadFile(drive);
|
|
160
|
+
|
|
161
|
+
// Example: Send file via email
|
|
162
|
+
const { stream } = await driveReadFile(fileId);
|
|
163
|
+
await sendEmail({
|
|
164
|
+
attachments: [{ filename: "report.pdf", content: stream }],
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Example: Process file contents
|
|
168
|
+
const { stream } = await driveReadFile(fileId);
|
|
169
|
+
const chunks = [];
|
|
170
|
+
for await (const chunk of stream) {
|
|
171
|
+
chunks.push(chunk);
|
|
172
|
+
}
|
|
173
|
+
const buffer = Buffer.concat(chunks);
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Get Local File Path:**
|
|
177
|
+
|
|
178
|
+
For scenarios requiring direct file system access, `driveFilePath()` provides the absolute path. Google Drive files are automatically downloaded to a local cache.
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { driveFilePath } from "@muhgholy/next-drive/server";
|
|
182
|
+
import fs from "fs";
|
|
183
|
+
|
|
184
|
+
// Get local path (downloads Google Drive files automatically)
|
|
185
|
+
const { path, mime, size, provider } = await driveFilePath(fileId);
|
|
186
|
+
|
|
187
|
+
// Use with synchronous file operations
|
|
188
|
+
const buffer = fs.readFileSync(path);
|
|
189
|
+
|
|
190
|
+
// Use with libraries requiring file paths
|
|
191
|
+
await sharp(path).resize(800, 600).toFile("output.jpg");
|
|
192
|
+
await ffmpeg(path).format("mp4").save("output.mp4");
|
|
193
|
+
|
|
194
|
+
// Google Drive files are cached at: storage/library/google/{fileId}.ext
|
|
195
|
+
// Local files use their original location
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Search & Trash
|
|
199
|
+
|
|
200
|
+
- **Search Scope**: Search automatically adapts to your current view. If you are browsing the Trash, searches will query deleted items. In the main Browser, searches query active files.
|
|
201
|
+
- **Trash Management**: "Delete" moves items to Trash. From Trash, you can "Restore" items or "Delete Forever". A dedicated "Empty Trash" button is available to clear all deleted items.
|
|
202
|
+
|
|
203
|
+
### Responsive Design
|
|
204
|
+
|
|
205
|
+
- **Desktop**: Features a unified single-row header containing Search, Group, Delete, Sort, View, and Trash controls.
|
|
206
|
+
- **Mobile**: Optimizes for small screens by separating the Search bar into a full-width top row and grouping action buttons in a scrollable toolbar below.
|
|
207
|
+
|
|
208
|
+
## API Endpoints
|
|
209
|
+
|
|
210
|
+
All operations use the `?action=` query parameter on your configured API endpoint:
|
|
211
|
+
|
|
212
|
+
| Action | Method | Description |
|
|
213
|
+
| ----------------- | ------ | -------------------------------------------------------- |
|
|
214
|
+
| `upload` | POST | Chunked file upload handling |
|
|
215
|
+
| `list` | GET | List files in a folder (supports `trashed` param) |
|
|
216
|
+
| `serve` | GET | Serve file content (supports resizing/format conversion) |
|
|
217
|
+
| `thumbnail` | GET | specific endpoint for file thumbnails |
|
|
218
|
+
| `rename` | PATCH | Rename a file or folder |
|
|
219
|
+
| `trash` | POST | Move items to trash (soft delete) |
|
|
220
|
+
| `deletePermanent` | DELETE | Permanently remove items |
|
|
221
|
+
| `restore` | POST | Restore items from trash |
|
|
222
|
+
| `emptyTrash` | DELETE | Permanently remove all trashed items |
|
|
223
|
+
| `createFolder` | POST | Create a new directory |
|
|
224
|
+
| `move` | POST | Move files/folders to a new parent |
|
|
225
|
+
| `search` | GET | Search by name (supports `trashed=true`) |
|
|
226
|
+
| `quota` | GET | Get current storage usage |
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
MIT
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/* src/client/styles.css */
|
|
2
|
+
:root {
|
|
3
|
+
--background: 0 0% 100%;
|
|
4
|
+
--foreground: 222.2 84% 4.9%;
|
|
5
|
+
--card: 0 0% 100%;
|
|
6
|
+
--card-foreground: 222.2 84% 4.9%;
|
|
7
|
+
--popover: 0 0% 100%;
|
|
8
|
+
--popover-foreground: 222.2 84% 4.9%;
|
|
9
|
+
--primary: 222.2 47.4% 11.2%;
|
|
10
|
+
--primary-foreground: 210 40% 98%;
|
|
11
|
+
--secondary: 210 40% 96.1%;
|
|
12
|
+
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
13
|
+
--muted: 210 40% 96.1%;
|
|
14
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
15
|
+
--accent: 210 40% 96.1%;
|
|
16
|
+
--accent-foreground: 222.2 47.4% 11.2%;
|
|
17
|
+
--destructive: 0 84.2% 60.2%;
|
|
18
|
+
--destructive-foreground: 210 40% 98%;
|
|
19
|
+
--border: 214.3 31.8% 91.4%;
|
|
20
|
+
--input: 214.3 31.8% 91.4%;
|
|
21
|
+
--ring: 222.2 84% 4.9%;
|
|
22
|
+
--radius: 0.5rem;
|
|
23
|
+
}
|
|
24
|
+
.dark {
|
|
25
|
+
--background: 222.2 84% 4.9%;
|
|
26
|
+
--foreground: 210 40% 98%;
|
|
27
|
+
--card: 222.2 84% 4.9%;
|
|
28
|
+
--card-foreground: 210 40% 98%;
|
|
29
|
+
--popover: 222.2 84% 4.9%;
|
|
30
|
+
--popover-foreground: 210 40% 98%;
|
|
31
|
+
--primary: 210 40% 98%;
|
|
32
|
+
--primary-foreground: 222.2 47.4% 11.2%;
|
|
33
|
+
--secondary: 217.2 32.6% 17.5%;
|
|
34
|
+
--secondary-foreground: 210 40% 98%;
|
|
35
|
+
--muted: 217.2 32.6% 17.5%;
|
|
36
|
+
--muted-foreground: 215 20.2% 65.1%;
|
|
37
|
+
--accent: 217.2 32.6% 17.5%;
|
|
38
|
+
--accent-foreground: 210 40% 98%;
|
|
39
|
+
--destructive: 0 62.8% 30.6%;
|
|
40
|
+
--destructive-foreground: 210 40% 98%;
|
|
41
|
+
--border: 217.2 32.6% 17.5%;
|
|
42
|
+
--input: 217.2 32.6% 17.5%;
|
|
43
|
+
--ring: 212.7 26.8% 83.9%;
|
|
44
|
+
}
|
|
45
|
+
* {
|
|
46
|
+
border-color: hsl(var(--border));
|
|
47
|
+
}
|
|
48
|
+
/*# sourceMappingURL=index.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/client/styles.css"],"sourcesContent":[":root {\n --background: 0 0% 100%;\n --foreground: 222.2 84% 4.9%;\n\n --card: 0 0% 100%;\n --card-foreground: 222.2 84% 4.9%;\n\n --popover: 0 0% 100%;\n --popover-foreground: 222.2 84% 4.9%;\n\n --primary: 222.2 47.4% 11.2%;\n --primary-foreground: 210 40% 98%;\n\n --secondary: 210 40% 96.1%;\n --secondary-foreground: 222.2 47.4% 11.2%;\n\n --muted: 210 40% 96.1%;\n --muted-foreground: 215.4 16.3% 46.9%;\n\n --accent: 210 40% 96.1%;\n --accent-foreground: 222.2 47.4% 11.2%;\n\n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 214.3 31.8% 91.4%;\n --input: 214.3 31.8% 91.4%;\n --ring: 222.2 84% 4.9%;\n\n --radius: 0.5rem;\n}\n\n.dark {\n --background: 222.2 84% 4.9%;\n --foreground: 210 40% 98%;\n\n --card: 222.2 84% 4.9%;\n --card-foreground: 210 40% 98%;\n\n --popover: 222.2 84% 4.9%;\n --popover-foreground: 210 40% 98%;\n\n --primary: 210 40% 98%;\n --primary-foreground: 222.2 47.4% 11.2%;\n\n --secondary: 217.2 32.6% 17.5%;\n --secondary-foreground: 210 40% 98%;\n\n --muted: 217.2 32.6% 17.5%;\n --muted-foreground: 215 20.2% 65.1%;\n\n --accent: 217.2 32.6% 17.5%;\n --accent-foreground: 210 40% 98%;\n\n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 210 40% 98%;\n\n --border: 217.2 32.6% 17.5%;\n --input: 217.2 32.6% 17.5%;\n --ring: 212.7 26.8% 83.9%;\n}\n\n* {\n border-color: hsl(var(--border));\n}"],"mappings":";AAAA;AACI,gBAAc,EAAE,GAAG;AACnB,gBAAc,MAAM,IAAI;AAExB,UAAQ,EAAE,GAAG;AACb,qBAAmB,MAAM,IAAI;AAE7B,aAAW,EAAE,GAAG;AAChB,wBAAsB,MAAM,IAAI;AAEhC,aAAW,MAAM,MAAM;AACvB,wBAAsB,IAAI,IAAI;AAE9B,eAAa,IAAI,IAAI;AACrB,0BAAwB,MAAM,MAAM;AAEpC,WAAS,IAAI,IAAI;AACjB,sBAAoB,MAAM,MAAM;AAEhC,YAAU,IAAI,IAAI;AAClB,uBAAqB,MAAM,MAAM;AAEjC,iBAAe,EAAE,MAAM;AACvB,4BAA0B,IAAI,IAAI;AAElC,YAAU,MAAM,MAAM;AACtB,WAAS,MAAM,MAAM;AACrB,UAAQ,MAAM,IAAI;AAElB,YAAU;AACd;AAEA,CAAC;AACG,gBAAc,MAAM,IAAI;AACxB,gBAAc,IAAI,IAAI;AAEtB,UAAQ,MAAM,IAAI;AAClB,qBAAmB,IAAI,IAAI;AAE3B,aAAW,MAAM,IAAI;AACrB,wBAAsB,IAAI,IAAI;AAE9B,aAAW,IAAI,IAAI;AACnB,wBAAsB,MAAM,MAAM;AAElC,eAAa,MAAM,MAAM;AACzB,0BAAwB,IAAI,IAAI;AAEhC,WAAS,MAAM,MAAM;AACrB,sBAAoB,IAAI,MAAM;AAE9B,YAAU,MAAM,MAAM;AACtB,uBAAqB,IAAI,IAAI;AAE7B,iBAAe,EAAE,MAAM;AACvB,4BAA0B,IAAI,IAAI;AAElC,YAAU,MAAM,MAAM;AACtB,WAAS,MAAM,MAAM;AACrB,UAAQ,MAAM,MAAM;AACxB;AAEA;AACI,gBAAc,IAAI,IAAI;AAC1B;","names":[]}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { l as TDrivePathItem, d as TDatabaseDrive, m as TDriveQuota, i as TDriveAPIResponse, n as TDriveUploadState, e as TDriveFile } from '../index-DE7-rwJm.js';
|
|
3
|
+
|
|
4
|
+
type TDriveContext = {
|
|
5
|
+
apiEndpoint: string;
|
|
6
|
+
currentFolderId: string | null;
|
|
7
|
+
path: TDrivePathItem[];
|
|
8
|
+
items: TDatabaseDrive[];
|
|
9
|
+
allItems: Record<string, TDatabaseDrive[]>;
|
|
10
|
+
isLoading: boolean;
|
|
11
|
+
error: string | null;
|
|
12
|
+
quota: TDriveQuota | null;
|
|
13
|
+
accounts: {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
email: string;
|
|
17
|
+
provider: 'GOOGLE';
|
|
18
|
+
}[];
|
|
19
|
+
activeAccountId: string | null;
|
|
20
|
+
setActiveAccountId: (id: string | null) => void;
|
|
21
|
+
refreshAccounts: () => Promise<void>;
|
|
22
|
+
viewMode: 'GRID' | 'LIST';
|
|
23
|
+
setViewMode: (mode: 'GRID' | 'LIST') => void;
|
|
24
|
+
currentView: 'BROWSE' | 'TRASH' | 'SEARCH';
|
|
25
|
+
setCurrentView: (view: 'BROWSE' | 'TRASH' | 'SEARCH') => void;
|
|
26
|
+
searchQuery: string;
|
|
27
|
+
setSearchQuery: (query: string) => void;
|
|
28
|
+
searchScope: 'ACTIVE' | 'TRASH';
|
|
29
|
+
setSearchScope: (scope: 'ACTIVE' | 'TRASH') => void;
|
|
30
|
+
groupBy: 'NONE' | 'CREATED_AT';
|
|
31
|
+
setGroupBy: (group: 'NONE' | 'CREATED_AT') => void;
|
|
32
|
+
sortBy: {
|
|
33
|
+
field: string;
|
|
34
|
+
order: number;
|
|
35
|
+
};
|
|
36
|
+
setSortBy: (sort: {
|
|
37
|
+
field: string;
|
|
38
|
+
order: number;
|
|
39
|
+
}) => void;
|
|
40
|
+
selectionMode: {
|
|
41
|
+
type: 'SINGLE';
|
|
42
|
+
} | {
|
|
43
|
+
type: 'MULTIPLE';
|
|
44
|
+
maxFile?: number;
|
|
45
|
+
};
|
|
46
|
+
selectedFileIds: string[];
|
|
47
|
+
setSelectedFileIds: React.Dispatch<React.SetStateAction<string[]>>;
|
|
48
|
+
navigateToFolder: (item: {
|
|
49
|
+
id: string | null;
|
|
50
|
+
name: string;
|
|
51
|
+
} | null) => void;
|
|
52
|
+
navigateUp: () => void;
|
|
53
|
+
refreshItems: () => Promise<void>;
|
|
54
|
+
refreshQuota: () => Promise<void>;
|
|
55
|
+
moveItem: (itemId: string, targetFolderId: string) => Promise<void>;
|
|
56
|
+
deleteItems: (ids: string[]) => Promise<void>;
|
|
57
|
+
callAPI: <T>(action: string, options?: RequestInit & {
|
|
58
|
+
query?: Record<string, string>;
|
|
59
|
+
}) => Promise<TDriveAPIResponse<T>>;
|
|
60
|
+
setItems: (updater: React.SetStateAction<TDatabaseDrive[]>) => void;
|
|
61
|
+
setAllItems: React.Dispatch<React.SetStateAction<Record<string, TDatabaseDrive[]>>>;
|
|
62
|
+
loadMore: () => Promise<void>;
|
|
63
|
+
hasMore: boolean;
|
|
64
|
+
isLoadingMore: boolean;
|
|
65
|
+
};
|
|
66
|
+
declare const DriveProvider: (props: Readonly<{
|
|
67
|
+
children: ReactNode;
|
|
68
|
+
apiEndpoint: string;
|
|
69
|
+
initialActiveAccountId?: string | null;
|
|
70
|
+
initialSelectionMode?: {
|
|
71
|
+
type: "SINGLE";
|
|
72
|
+
} | {
|
|
73
|
+
type: "MULTIPLE";
|
|
74
|
+
maxFile?: number;
|
|
75
|
+
};
|
|
76
|
+
defaultSelectedFileIds?: string[];
|
|
77
|
+
}>) => React.JSX.Element;
|
|
78
|
+
declare const useDrive: () => TDriveContext;
|
|
79
|
+
|
|
80
|
+
declare const useUpload: (apiEndpoint: string, activeAccountId: string | null, onUploadComplete?: (item: any) => void) => {
|
|
81
|
+
uploads: TDriveUploadState[];
|
|
82
|
+
uploadFiles: (files: File[], folderId: string | null) => Promise<void>;
|
|
83
|
+
cancelUpload: (id: string) => Promise<void>;
|
|
84
|
+
cancelAllUploads: () => Promise<void>;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
declare const DriveFileChooser: (props: Readonly<{
|
|
88
|
+
value: TDriveFile | TDriveFile[] | null;
|
|
89
|
+
onChange: (files: TDriveFile | TDriveFile[] | null) => void;
|
|
90
|
+
multiple?: boolean;
|
|
91
|
+
accept?: string;
|
|
92
|
+
placeholder?: string;
|
|
93
|
+
className?: string;
|
|
94
|
+
disabled?: boolean;
|
|
95
|
+
error?: boolean;
|
|
96
|
+
helperText?: string;
|
|
97
|
+
}>) => React.JSX.Element;
|
|
98
|
+
|
|
99
|
+
declare const DriveExplorer: (props: Readonly<{
|
|
100
|
+
onItemClick?: (item: TDatabaseDrive) => void;
|
|
101
|
+
onItemDoubleClick?: (item: TDatabaseDrive) => void;
|
|
102
|
+
mimeFilter?: string;
|
|
103
|
+
className?: string;
|
|
104
|
+
selectableFolders?: boolean;
|
|
105
|
+
}>) => React.JSX.Element;
|
|
106
|
+
|
|
107
|
+
declare const DrivePathBar: () => React.JSX.Element;
|
|
108
|
+
|
|
109
|
+
declare const DriveUpload: (props: Readonly<{
|
|
110
|
+
compact?: boolean;
|
|
111
|
+
onComplete?: (item: unknown) => void;
|
|
112
|
+
}>) => React.JSX.Element;
|
|
113
|
+
|
|
114
|
+
declare const DriveFilePreview: (props: Readonly<{
|
|
115
|
+
item: TDatabaseDrive;
|
|
116
|
+
onClose: () => void;
|
|
117
|
+
}>) => React.JSX.Element | null;
|
|
118
|
+
|
|
119
|
+
declare const DriveStorageIndicator: (props: Readonly<{
|
|
120
|
+
compact?: boolean;
|
|
121
|
+
className?: string;
|
|
122
|
+
}>) => React.JSX.Element | null;
|
|
123
|
+
|
|
124
|
+
declare const DriveHeader: () => React.JSX.Element;
|
|
125
|
+
|
|
126
|
+
declare const DriveSidebar: () => React.JSX.Element;
|
|
127
|
+
|
|
128
|
+
export { DriveExplorer, DriveFileChooser, DriveFilePreview, DriveHeader, DrivePathBar, DriveProvider, DriveSidebar, DriveStorageIndicator, DriveUpload, type TDriveContext, TDriveFile, useDrive, useUpload };
|