add file browser component and widget
This commit is contained in:
331
widgets/file_browser_widget/pkg/README.md
Normal file
331
widgets/file_browser_widget/pkg/README.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# FileBrowser Widget
|
||||
|
||||
A powerful WebAssembly-based file browser widget that can be embedded in any web application. Built with Rust and Yew, compiled to WASM for maximum performance.
|
||||
|
||||
## Features
|
||||
|
||||
- 📁 **File & Directory Management**: Browse, create, delete files and directories
|
||||
- 📤 **Resumable Uploads**: Upload files with progress tracking using TUS protocol
|
||||
- 📥 **File Downloads**: Download files with proper MIME type handling
|
||||
- ✏️ **File Editing**: Built-in editors for text files and markdown with live preview
|
||||
- 🎨 **Modern UI**: Responsive Bootstrap-based interface with light/dark themes
|
||||
- 🔧 **Highly Configurable**: Extensive JavaScript API for customization
|
||||
- 🚀 **High Performance**: Compiled to WebAssembly for native-like performance
|
||||
- 🌐 **Cross-Browser**: Works in all modern browsers
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Installation
|
||||
|
||||
#### Via npm (recommended)
|
||||
```bash
|
||||
npm install @herocode/file-browser-widget
|
||||
```
|
||||
|
||||
#### Manual Download
|
||||
Download the latest release files:
|
||||
- `file_browser_widget.js`
|
||||
- `file_browser_widget_bg.wasm`
|
||||
|
||||
### 2. Include Dependencies
|
||||
|
||||
Add Bootstrap CSS and Icons to your HTML:
|
||||
```html
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css" rel="stylesheet">
|
||||
```
|
||||
|
||||
### 3. Create Container
|
||||
|
||||
Add a container element to your HTML:
|
||||
```html
|
||||
<div id="file-browser-container"></div>
|
||||
```
|
||||
|
||||
### 4. Initialize Widget
|
||||
|
||||
```javascript
|
||||
import init, {
|
||||
create_file_browser_widget,
|
||||
create_default_config
|
||||
} from '@herocode/file-browser-widget';
|
||||
|
||||
async function initFileBrowser() {
|
||||
// Initialize the WASM module
|
||||
await init();
|
||||
|
||||
// Create configuration
|
||||
const config = create_default_config('http://localhost:3001/files');
|
||||
config.set_theme('light');
|
||||
config.set_show_upload(true);
|
||||
config.set_show_download(true);
|
||||
config.set_show_delete(true);
|
||||
config.set_max_file_size(100 * 1024 * 1024); // 100MB
|
||||
|
||||
// Create and mount the widget
|
||||
const widget = create_file_browser_widget('file-browser-container', config);
|
||||
|
||||
console.log('FileBrowser widget initialized successfully!');
|
||||
}
|
||||
|
||||
// Initialize when page loads
|
||||
initFileBrowser().catch(console.error);
|
||||
```
|
||||
|
||||
## Configuration API
|
||||
|
||||
### WidgetConfig
|
||||
|
||||
The main configuration object for customizing the widget behavior:
|
||||
|
||||
```javascript
|
||||
const config = create_default_config('http://localhost:3001/files');
|
||||
|
||||
// File size limit (in bytes)
|
||||
config.set_max_file_size(50 * 1024 * 1024); // 50MB
|
||||
|
||||
// Feature toggles
|
||||
config.set_show_upload(true);
|
||||
config.set_show_download(true);
|
||||
config.set_show_delete(true);
|
||||
|
||||
// UI customization
|
||||
config.set_theme('dark'); // 'light' or 'dark'
|
||||
config.set_css_classes('my-custom-class');
|
||||
config.set_initial_path('documents/');
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `base_endpoint` | string | required | Backend API endpoint for file operations |
|
||||
| `max_file_size` | number | 104857600 | Maximum file size for uploads (bytes) |
|
||||
| `show_upload` | boolean | true | Enable/disable upload functionality |
|
||||
| `show_download` | boolean | true | Enable/disable download functionality |
|
||||
| `show_delete` | boolean | true | Enable/disable delete functionality |
|
||||
| `theme` | string | 'light' | UI theme ('light' or 'dark') |
|
||||
| `css_classes` | string | '' | Additional CSS classes for root element |
|
||||
| `initial_path` | string | '' | Initial directory path to display |
|
||||
|
||||
## JavaScript API
|
||||
|
||||
### Functions
|
||||
|
||||
#### `init()`
|
||||
Initialize the WASM module. Must be called before using other functions.
|
||||
|
||||
```javascript
|
||||
await init();
|
||||
```
|
||||
|
||||
#### `create_default_config(base_endpoint)`
|
||||
Create a default configuration object.
|
||||
|
||||
```javascript
|
||||
const config = create_default_config('http://localhost:3001/files');
|
||||
```
|
||||
|
||||
#### `create_file_browser_widget(container_id, config)`
|
||||
Create and mount a widget to a DOM element by ID.
|
||||
|
||||
```javascript
|
||||
const widget = create_file_browser_widget('my-container', config);
|
||||
```
|
||||
|
||||
#### `create_file_browser_widget_on_element(element, config)`
|
||||
Create and mount a widget to a specific DOM element.
|
||||
|
||||
```javascript
|
||||
const element = document.getElementById('my-container');
|
||||
const widget = create_file_browser_widget_on_element(element, config);
|
||||
```
|
||||
|
||||
#### `check_browser_compatibility()`
|
||||
Check if the current browser supports the widget.
|
||||
|
||||
```javascript
|
||||
if (!check_browser_compatibility()) {
|
||||
console.error('Browser not supported');
|
||||
}
|
||||
```
|
||||
|
||||
#### `get_version()`
|
||||
Get the widget version.
|
||||
|
||||
```javascript
|
||||
console.log('Widget version:', get_version());
|
||||
```
|
||||
|
||||
### Widget Handle
|
||||
|
||||
The widget functions return a handle that can be used to manage the widget:
|
||||
|
||||
```javascript
|
||||
const widget = create_file_browser_widget('container', config);
|
||||
|
||||
// Destroy the widget
|
||||
widget.destroy();
|
||||
```
|
||||
|
||||
## Backend Requirements
|
||||
|
||||
The widget expects a REST API compatible with the following endpoints:
|
||||
|
||||
### File Listing
|
||||
```
|
||||
GET /files/list/<path>
|
||||
Response: JSON array of file/directory objects
|
||||
```
|
||||
|
||||
### Directory Creation
|
||||
```
|
||||
POST /files/dirs/<path>
|
||||
Creates a new directory at the specified path
|
||||
```
|
||||
|
||||
### File/Directory Deletion
|
||||
```
|
||||
DELETE /files/delete/<path>
|
||||
Deletes the file or directory at the specified path
|
||||
```
|
||||
|
||||
### File Upload (TUS Protocol)
|
||||
```
|
||||
POST /files/upload
|
||||
Handles resumable file uploads using TUS protocol
|
||||
```
|
||||
|
||||
### File Download
|
||||
```
|
||||
GET /files/download/<path>
|
||||
Returns the file content with appropriate headers
|
||||
```
|
||||
|
||||
### Example Backend Response Format
|
||||
|
||||
File listing response:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"name": "document.pdf",
|
||||
"path": "documents/document.pdf",
|
||||
"size": 1024000,
|
||||
"is_directory": false,
|
||||
"modified": "2023-12-01T10:30:00Z"
|
||||
},
|
||||
{
|
||||
"name": "images",
|
||||
"path": "documents/images",
|
||||
"size": 0,
|
||||
"is_directory": true,
|
||||
"modified": "2023-12-01T09:15:00Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Custom Styling
|
||||
|
||||
Add custom CSS to style the widget:
|
||||
|
||||
```css
|
||||
.file-browser-widget {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.file-browser-widget .card {
|
||||
border: none;
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple Widgets
|
||||
|
||||
You can create multiple widget instances on the same page:
|
||||
|
||||
```javascript
|
||||
// Widget 1
|
||||
const config1 = create_default_config('http://api1.example.com/files');
|
||||
const widget1 = create_file_browser_widget('container1', config1);
|
||||
|
||||
// Widget 2
|
||||
const config2 = create_default_config('http://api2.example.com/files');
|
||||
config2.set_theme('dark');
|
||||
const widget2 = create_file_browser_widget('container2', config2);
|
||||
```
|
||||
|
||||
### Error Handling
|
||||
|
||||
```javascript
|
||||
try {
|
||||
const widget = create_file_browser_widget('container', config);
|
||||
} catch (error) {
|
||||
console.error('Failed to create widget:', error);
|
||||
// Show fallback UI
|
||||
}
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Building from Source
|
||||
|
||||
1. Install Rust and wasm-pack:
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
cargo install wasm-pack
|
||||
```
|
||||
|
||||
2. Build the widget:
|
||||
```bash
|
||||
./build.sh
|
||||
```
|
||||
|
||||
3. Test locally:
|
||||
```bash
|
||||
npm run dev
|
||||
# Open http://localhost:8000/example.html
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
widgets/file_browser_widget/
|
||||
├── src/
|
||||
│ └── lib.rs # Main widget implementation
|
||||
├── dist/ # Built distribution files
|
||||
├── pkg/ # wasm-pack output
|
||||
├── Cargo.toml # Rust dependencies
|
||||
├── package.json # npm package config
|
||||
├── build.sh # Build script
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## Browser Support
|
||||
|
||||
- Chrome 57+
|
||||
- Firefox 52+
|
||||
- Safari 11+
|
||||
- Edge 16+
|
||||
|
||||
The widget requires WebAssembly support and modern JavaScript features.
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see LICENSE file for details.
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Add tests if applicable
|
||||
5. Submit a pull request
|
||||
|
||||
## Support
|
||||
|
||||
- 📖 [Documentation](https://github.com/herocode/framework)
|
||||
- 🐛 [Issue Tracker](https://github.com/herocode/framework/issues)
|
||||
- 💬 [Discussions](https://github.com/herocode/framework/discussions)
|
111
widgets/file_browser_widget/pkg/file_browser_widget.d.ts
vendored
Normal file
111
widgets/file_browser_widget/pkg/file_browser_widget.d.ts
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export function main(): void;
|
||||
/**
|
||||
* Create and mount a FileBrowser widget to the specified DOM element
|
||||
*/
|
||||
export function create_file_browser_widget(container_id: string, config: JSWidgetConfig): FileBrowserWidgetHandle;
|
||||
/**
|
||||
* Create and mount a FileBrowser widget to a specific DOM element
|
||||
*/
|
||||
export function create_file_browser_widget_on_element(element: Element, config: JSWidgetConfig): FileBrowserWidgetHandle;
|
||||
/**
|
||||
* Utility function to create a default configuration
|
||||
*/
|
||||
export function create_default_config(base_endpoint: string): JSWidgetConfig;
|
||||
/**
|
||||
* Get version information
|
||||
*/
|
||||
export function get_version(): string;
|
||||
/**
|
||||
* Check if the widget is compatible with the current browser
|
||||
*/
|
||||
export function check_browser_compatibility(): boolean;
|
||||
/**
|
||||
* Handle for managing the widget instance
|
||||
*/
|
||||
export class FileBrowserWidgetHandle {
|
||||
private constructor();
|
||||
free(): void;
|
||||
/**
|
||||
* Destroy the widget instance
|
||||
*/
|
||||
destroy(): void;
|
||||
/**
|
||||
* Update the widget configuration
|
||||
*/
|
||||
update_config(_config: JSWidgetConfig): void;
|
||||
}
|
||||
/**
|
||||
* JavaScript-compatible configuration wrapper
|
||||
*/
|
||||
export class JSWidgetConfig {
|
||||
free(): void;
|
||||
constructor(base_endpoint: string);
|
||||
setMaxFileSize(size: number): void;
|
||||
setShowUpload(show: boolean): void;
|
||||
setShowDownload(show: boolean): void;
|
||||
setShowDelete(show: boolean): void;
|
||||
setTheme(theme: string): void;
|
||||
setCssClasses(classes: string): void;
|
||||
setInitialPath(path: string): void;
|
||||
}
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly main: () => void;
|
||||
readonly __wbg_jswidgetconfig_free: (a: number, b: number) => void;
|
||||
readonly jswidgetconfig_new: (a: number, b: number) => number;
|
||||
readonly jswidgetconfig_setMaxFileSize: (a: number, b: number) => void;
|
||||
readonly jswidgetconfig_setShowUpload: (a: number, b: number) => void;
|
||||
readonly jswidgetconfig_setShowDownload: (a: number, b: number) => void;
|
||||
readonly jswidgetconfig_setShowDelete: (a: number, b: number) => void;
|
||||
readonly jswidgetconfig_setTheme: (a: number, b: number, c: number) => void;
|
||||
readonly jswidgetconfig_setCssClasses: (a: number, b: number, c: number) => void;
|
||||
readonly jswidgetconfig_setInitialPath: (a: number, b: number, c: number) => void;
|
||||
readonly __wbg_filebrowserwidgethandle_free: (a: number, b: number) => void;
|
||||
readonly filebrowserwidgethandle_destroy: (a: number) => void;
|
||||
readonly filebrowserwidgethandle_update_config: (a: number, b: number) => void;
|
||||
readonly create_file_browser_widget: (a: number, b: number, c: number) => [number, number, number];
|
||||
readonly create_file_browser_widget_on_element: (a: any, b: number) => [number, number, number];
|
||||
readonly create_default_config: (a: number, b: number) => number;
|
||||
readonly get_version: () => [number, number];
|
||||
readonly check_browser_compatibility: () => number;
|
||||
readonly __wbindgen_exn_store: (a: number) => void;
|
||||
readonly __externref_table_alloc: () => number;
|
||||
readonly __wbindgen_export_2: WebAssembly.Table;
|
||||
readonly __wbindgen_malloc: (a: number, b: number) => number;
|
||||
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||
readonly __externref_drop_slice: (a: number, b: number) => void;
|
||||
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
|
||||
readonly __wbindgen_export_7: WebAssembly.Table;
|
||||
readonly __externref_table_dealloc: (a: number) => void;
|
||||
readonly closure26_externref_shim: (a: number, b: number, c: any, d: any) => void;
|
||||
readonly closure23_externref_shim: (a: number, b: number, c: any, d: any, e: any) => void;
|
||||
readonly closure48_externref_shim: (a: number, b: number, c: any) => void;
|
||||
readonly closure58_externref_shim: (a: number, b: number, c: any) => void;
|
||||
readonly __wbindgen_start: () => void;
|
||||
}
|
||||
|
||||
export type SyncInitInput = BufferSource | WebAssembly.Module;
|
||||
/**
|
||||
* Instantiates the given `module`, which can either be bytes or
|
||||
* a precompiled `WebAssembly.Module`.
|
||||
*
|
||||
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
|
||||
*
|
||||
* @returns {InitOutput}
|
||||
*/
|
||||
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
|
||||
|
||||
/**
|
||||
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||
*
|
||||
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
|
||||
*
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
|
1074
widgets/file_browser_widget/pkg/file_browser_widget.js
Normal file
1074
widgets/file_browser_widget/pkg/file_browser_widget.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
widgets/file_browser_widget/pkg/file_browser_widget_bg.wasm
Normal file
BIN
widgets/file_browser_widget/pkg/file_browser_widget_bg.wasm
Normal file
Binary file not shown.
35
widgets/file_browser_widget/pkg/file_browser_widget_bg.wasm.d.ts
vendored
Normal file
35
widgets/file_browser_widget/pkg/file_browser_widget_bg.wasm.d.ts
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export const memory: WebAssembly.Memory;
|
||||
export const main: () => void;
|
||||
export const __wbg_jswidgetconfig_free: (a: number, b: number) => void;
|
||||
export const jswidgetconfig_new: (a: number, b: number) => number;
|
||||
export const jswidgetconfig_setMaxFileSize: (a: number, b: number) => void;
|
||||
export const jswidgetconfig_setShowUpload: (a: number, b: number) => void;
|
||||
export const jswidgetconfig_setShowDownload: (a: number, b: number) => void;
|
||||
export const jswidgetconfig_setShowDelete: (a: number, b: number) => void;
|
||||
export const jswidgetconfig_setTheme: (a: number, b: number, c: number) => void;
|
||||
export const jswidgetconfig_setCssClasses: (a: number, b: number, c: number) => void;
|
||||
export const jswidgetconfig_setInitialPath: (a: number, b: number, c: number) => void;
|
||||
export const __wbg_filebrowserwidgethandle_free: (a: number, b: number) => void;
|
||||
export const filebrowserwidgethandle_destroy: (a: number) => void;
|
||||
export const filebrowserwidgethandle_update_config: (a: number, b: number) => void;
|
||||
export const create_file_browser_widget: (a: number, b: number, c: number) => [number, number, number];
|
||||
export const create_file_browser_widget_on_element: (a: any, b: number) => [number, number, number];
|
||||
export const create_default_config: (a: number, b: number) => number;
|
||||
export const get_version: () => [number, number];
|
||||
export const check_browser_compatibility: () => number;
|
||||
export const __wbindgen_exn_store: (a: number) => void;
|
||||
export const __externref_table_alloc: () => number;
|
||||
export const __wbindgen_export_2: WebAssembly.Table;
|
||||
export const __wbindgen_malloc: (a: number, b: number) => number;
|
||||
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
||||
export const __externref_drop_slice: (a: number, b: number) => void;
|
||||
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
||||
export const __wbindgen_export_7: WebAssembly.Table;
|
||||
export const __externref_table_dealloc: (a: number) => void;
|
||||
export const closure26_externref_shim: (a: number, b: number, c: any, d: any) => void;
|
||||
export const closure23_externref_shim: (a: number, b: number, c: any, d: any, e: any) => void;
|
||||
export const closure48_externref_shim: (a: number, b: number, c: any) => void;
|
||||
export const closure58_externref_shim: (a: number, b: number, c: any) => void;
|
||||
export const __wbindgen_start: () => void;
|
21
widgets/file_browser_widget/pkg/package.json
Normal file
21
widgets/file_browser_widget/pkg/package.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "file_browser_widget",
|
||||
"type": "module",
|
||||
"description": "WASM widget for embedding the FileBrowser component in web applications",
|
||||
"version": "0.1.0",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/herocode/framework"
|
||||
},
|
||||
"files": [
|
||||
"file_browser_widget_bg.wasm",
|
||||
"file_browser_widget.js",
|
||||
"file_browser_widget.d.ts"
|
||||
],
|
||||
"main": "file_browser_widget.js",
|
||||
"types": "file_browser_widget.d.ts",
|
||||
"sideEffects": [
|
||||
"./snippets/*"
|
||||
]
|
||||
}
|
Reference in New Issue
Block a user