File Manager
File management utilities composed from existing components: tree browser, file list, upload dropzone, and storage info cards.
File Browser
Preview
home / projects / documents
| Name | Size | Modified | ||
|---|---|---|---|---|
|
assets
|
-- | Feb 5, 2026 | ||
|
backups
|
-- | Jan 28, 2026 | ||
|
report-2026.pdf
|
2.4 MB | Feb 3, 2026 | ||
|
data-export.csv
|
845 KB | Feb 1, 2026 | ||
|
config.json
|
1.2 KB | Jan 15, 2026 |
5 items · 1 selected
Total: 3.4 MB
<div class="card">
<div class="card-body p-0">
<!-- Toolbar -->
<div class="flex items-center justify-between gap-2 px-4 py-2 border-b border-base-300">
<div class="flex items-center gap-2">
<button class="btn btn-sm btn-ghost">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6"/></svg>
</button>
<button class="btn btn-sm btn-ghost">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m9 18 6-6-6-6"/></svg>
</button>
<div class="text-sm text-base-content/60">
<span>home</span> / <span>projects</span> / <span class="font-medium text-base-content">documents</span>
</div>
</div>
<div class="flex items-center gap-1">
<button class="btn btn-sm btn-ghost" title="Grid view">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
</button>
<button class="btn btn-sm btn-ghost btn-active" title="List view">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>
</button>
</div>
</div>
<!-- File list -->
<table class="table">
<thead>
<tr>
<th class="w-8"><input type="checkbox"></th>
<th>Name</th>
<th>Size</th>
<th>Modified</th>
<th class="w-16"></th>
</tr>
</thead>
<tbody>
<tr class="cursor-pointer hover:bg-base-200/50">
<td><input type="checkbox"></td>
<td>
<div class="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="size-5 text-warning" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
<span class="font-medium">assets</span>
</div>
</td>
<td class="text-base-content/60">--</td>
<td class="text-base-content/60">Feb 5, 2026</td>
<td></td>
</tr>
<tr class="cursor-pointer hover:bg-base-200/50">
<td><input type="checkbox"></td>
<td>
<div class="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="size-5 text-warning" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
<span class="font-medium">backups</span>
</div>
</td>
<td class="text-base-content/60">--</td>
<td class="text-base-content/60">Jan 28, 2026</td>
<td></td>
</tr>
<tr class="cursor-pointer hover:bg-base-200/50 bg-primary/5">
<td><input type="checkbox" checked></td>
<td>
<div class="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="size-5 text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
<span class="font-medium">report-2026.pdf</span>
</div>
</td>
<td class="text-base-content/60">2.4 MB</td>
<td class="text-base-content/60">Feb 3, 2026</td>
<td>
<button class="btn btn-sm btn-ghost">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
</button>
</td>
</tr>
<tr class="cursor-pointer hover:bg-base-200/50">
<td><input type="checkbox"></td>
<td>
<div class="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="size-5 text-success" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
<span class="font-medium">data-export.csv</span>
</div>
</td>
<td class="text-base-content/60">845 KB</td>
<td class="text-base-content/60">Feb 1, 2026</td>
<td>
<button class="btn btn-sm btn-ghost">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
</button>
</td>
</tr>
<tr class="cursor-pointer hover:bg-base-200/50">
<td><input type="checkbox"></td>
<td>
<div class="flex items-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" class="size-5 text-base-content/40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
<span class="font-medium">config.json</span>
</div>
</td>
<td class="text-base-content/60">1.2 KB</td>
<td class="text-base-content/60">Jan 15, 2026</td>
<td>
<button class="btn btn-sm btn-ghost">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
</button>
</td>
</tr>
</tbody>
</table>
<!-- Footer -->
<div class="flex items-center justify-between px-4 py-2 border-t border-base-300 text-sm text-base-content/60">
<span>5 items · 1 selected</span>
<span>Total: 3.4 MB</span>
</div>
</div>
</div> Requires: ux.min.css
<div class="bg-base-100 border border-base-300 rounded-box overflow-hidden">
<!-- Toolbar -->
<div class="flex items-center justify-between gap-2 px-4 py-2 border-b border-base-300">
<div class="flex items-center gap-2">
<button class="inline-flex items-center justify-center w-8 h-8 rounded-field hover:bg-base-200">
<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m15 18-6-6 6-6"/></svg>
</button>
<button class="inline-flex items-center justify-center w-8 h-8 rounded-field hover:bg-base-200">
<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m9 18 6-6-6-6"/></svg>
</button>
<div class="text-sm text-base-content/60">
home / projects / <span class="font-medium text-base-content">documents</span>
</div>
</div>
<div class="flex items-center gap-1">
<button class="inline-flex items-center justify-center w-8 h-8 rounded-field hover:bg-base-200">
<svg class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
</button>
</div>
</div>
<!-- File rows -->
<div class="flex flex-col divide-y divide-base-300">
<div class="flex items-center gap-3 px-4 py-2.5 cursor-pointer hover:bg-base-200/50">
<svg class="size-5 text-warning shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
<span class="flex-1 font-medium text-sm">assets</span>
<span class="text-xs text-base-content/50">Feb 5, 2026</span>
</div>
<div class="flex items-center gap-3 px-4 py-2.5 cursor-pointer hover:bg-base-200/50">
<svg class="size-5 text-primary shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
<span class="flex-1 font-medium text-sm">report-2026.pdf</span>
<span class="text-xs text-base-content/50">2.4 MB</span>
</div>
<div class="flex items-center gap-3 px-4 py-2.5 cursor-pointer hover:bg-base-200/50">
<svg class="size-5 text-success shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
<span class="flex-1 font-medium text-sm">data-export.csv</span>
<span class="text-xs text-base-content/50">845 KB</span>
</div>
</div>
<!-- Footer -->
<div class="flex items-center justify-between px-4 py-2 border-t border-base-300 text-xs text-base-content/50">
<span>3 items</span>
<span>Total: 3.2 MB</span>
</div>
</div> Requires: tw.min.css
// Navigate into folder:
// row.addEventListener('dblclick', () => loadFolder(path));
// Select file:
// row.addEventListener('click', () => row.classList.toggle('bg-primary/5'));
// Download:
// window.location.href = downloadUrl; Sidebar Tree + File List
Preview
Explorer
-
media
-
documents 3
-
images
-
-
backups
documents (3 files)
report-2026.pdf
2.4 MBFeb 3, 2026
data-export.csv
845 KBFeb 1, 2026
config.json
1.2 KBJan 15, 2026
<div class="split-pane" style="height: 400px;">
<!-- Left: Tree -->
<div class="split-pane-panel" style="width: 240px; min-width: 180px;">
<div class="p-3 border-b border-base-300">
<p class="text-xs font-semibold text-base-content/50 uppercase tracking-wider">Explorer</p>
</div>
<div class="tree tree-sm p-2">
<ul class="tree-list">
<li class="tree-node">
<div class="tree-item">
<span class="tree-toggle tree-toggle-expanded"><svg viewBox="0 0 10 10" class="size-3.5"><path d="M3 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></span>
<span class="tree-icon tree-icon-folder"><svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg></span>
<span class="tree-label">media</span>
</div>
<ul class="tree-list tree-list-nested">
<li class="tree-node">
<div class="tree-item tree-item-selected">
<span class="tree-toggle tree-toggle-expanded"><svg viewBox="0 0 10 10" class="size-3.5"><path d="M3 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></span>
<span class="tree-icon tree-icon-folder"><svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg></span>
<span class="tree-label">documents</span>
<span class="tree-badge">3</span>
</div>
</li>
<li class="tree-node">
<div class="tree-item">
<span class="tree-toggle tree-toggle-empty"><svg viewBox="0 0 10 10" class="size-3.5"><path d="M3 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></span>
<span class="tree-icon tree-icon-folder"><svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg></span>
<span class="tree-label">images</span>
</div>
</li>
</ul>
</li>
<li class="tree-node">
<div class="tree-item">
<span class="tree-toggle tree-toggle-empty"><svg viewBox="0 0 10 10" class="size-3.5"><path d="M3 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg></span>
<span class="tree-icon tree-icon-folder"><svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg></span>
<span class="tree-label">backups</span>
</div>
</li>
</ul>
</div>
</div>
<!-- Divider -->
<div class="split-pane-divider"></div>
<!-- Right: Files -->
<div class="split-pane-panel flex-1 overflow-auto">
<div class="p-3 border-b border-base-300 flex items-center justify-between">
<p class="text-sm font-medium">documents <span class="text-base-content/40">(3 files)</span></p>
<button class="btn btn-sm color-primary">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
Upload
</button>
</div>
<div class="upload-files p-3">
<div class="upload-file upload-file-success">
<div class="upload-preview">
<svg xmlns="http://www.w3.org/2000/svg" class="upload-preview-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
</div>
<div class="upload-file-info">
<div class="upload-file-name">report-2026.pdf</div>
<div class="upload-file-meta"><span>2.4 MB</span><span>Feb 3, 2026</span></div>
</div>
<div class="upload-file-actions">
<button class="upload-file-action" title="Download">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
</button>
<button class="upload-file-action upload-file-action-danger" title="Delete">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
</button>
</div>
</div>
<div class="upload-file upload-file-success">
<div class="upload-preview">
<svg xmlns="http://www.w3.org/2000/svg" class="upload-preview-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
</div>
<div class="upload-file-info">
<div class="upload-file-name">data-export.csv</div>
<div class="upload-file-meta"><span>845 KB</span><span>Feb 1, 2026</span></div>
</div>
<div class="upload-file-actions">
<button class="upload-file-action" title="Download">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
</button>
<button class="upload-file-action upload-file-action-danger" title="Delete">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
</button>
</div>
</div>
<div class="upload-file">
<div class="upload-preview">
<svg xmlns="http://www.w3.org/2000/svg" class="upload-preview-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
</div>
<div class="upload-file-info">
<div class="upload-file-name">config.json</div>
<div class="upload-file-meta"><span>1.2 KB</span><span>Jan 15, 2026</span></div>
</div>
<div class="upload-file-actions">
<button class="upload-file-action" title="Download">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
</button>
<button class="upload-file-action upload-file-action-danger" title="Delete">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
</button>
</div>
</div>
</div>
</div>
</div> Requires: ux.min.css
<div class="flex border border-base-300 rounded-box overflow-hidden" style="height: 400px;">
<!-- Sidebar tree -->
<div class="w-60 shrink-0 border-r border-base-300 overflow-y-auto">
<div class="p-3 border-b border-base-300">
<p class="text-xs font-semibold text-base-content/50 uppercase tracking-wider">Explorer</p>
</div>
<div class="p-2 text-sm select-none">
<ul class="list-none m-0 p-0">
<li>
<div class="flex items-center gap-1 px-2 py-1 rounded-field cursor-pointer hover:bg-base-200">
<svg class="size-3.5 text-base-content/40 rotate-90" viewBox="0 0 10 10"><path d="M3 1l4 4-4 4" fill="none" stroke="currentColor" stroke-width="1.5"/></svg>
<svg class="size-4 text-warning" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
<span class="flex-1 truncate">media</span>
</div>
<ul class="list-none m-0 pl-4">
<li>
<div class="flex items-center gap-1 px-2 py-1 rounded-field cursor-pointer bg-primary/10 text-primary">
<svg class="size-4 text-warning" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
<span class="flex-1 truncate font-medium">documents</span>
<span class="text-xs bg-primary/20 text-primary px-1.5 rounded-full">3</span>
</div>
</li>
</ul>
</li>
</ul>
</div>
</div>
<!-- Files panel -->
<div class="flex-1 flex flex-col overflow-auto">
<div class="p-3 border-b border-base-300 flex items-center justify-between shrink-0">
<p class="text-sm font-medium">documents <span class="text-base-content/40">(3 files)</span></p>
</div>
<div class="flex flex-col gap-1 p-2 flex-1">
<div class="flex items-center gap-3 px-3 py-2 rounded-field hover:bg-base-200/50 cursor-pointer">
<svg class="size-5 text-primary shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium truncate">report-2026.pdf</div>
<div class="text-xs text-base-content/50">2.4 MB</div>
</div>
</div>
<div class="flex items-center gap-3 px-3 py-2 rounded-field hover:bg-base-200/50 cursor-pointer">
<svg class="size-5 text-success shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium truncate">data-export.csv</div>
<div class="text-xs text-base-content/50">845 KB</div>
</div>
</div>
</div>
</div>
</div> Requires: tw.min.css
// Load folder contents via HTMX:
// <div hx-get="/api/files?dir=media/documents"
// hx-trigger="load" hx-swap="innerHTML">
// Or fetch with JS:
// const files = await fetch('/api/files?dir=' + path).then(r => r.json()); Storage Info Card
Preview
Disk Usage
Storage
68.2 GB used
of 100 GB
Database
42.1 GB
Media files
18.4 GB
Backups
5.2 GB
Other
2.5 GB
<div class="card" style="max-width: 360px;">
<div class="card-body">
<div class="flex items-center gap-3 mb-4">
<div class="flex items-center justify-center w-10 h-10 rounded-field bg-primary/10">
<svg xmlns="http://www.w3.org/2000/svg" class="size-5 text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>
</div>
<div>
<p class="text-xs text-base-content/50 uppercase font-semibold">Disk Usage</p>
<p class="text-lg font-bold">Storage</p>
</div>
</div>
<!-- Main bar -->
<div class="w-full h-3 bg-base-200 rounded-full overflow-hidden mb-2">
<div class="h-full rounded-full" style="width: 68%; background: linear-gradient(90deg, var(--color-primary), var(--color-info));"></div>
</div>
<div class="flex items-center justify-between text-sm mb-4">
<span class="font-semibold">68.2 GB used</span>
<span class="text-base-content/50">of 100 GB</span>
</div>
<!-- Breakdown -->
<div class="flex flex-col gap-2">
<div class="flex items-center justify-between text-sm">
<div class="flex items-center gap-2">
<span class="w-2.5 h-2.5 rounded-full bg-primary"></span>
<span>Database</span>
</div>
<span class="font-medium">42.1 GB</span>
</div>
<div class="flex items-center justify-between text-sm">
<div class="flex items-center gap-2">
<span class="w-2.5 h-2.5 rounded-full bg-info"></span>
<span>Media files</span>
</div>
<span class="font-medium">18.4 GB</span>
</div>
<div class="flex items-center justify-between text-sm">
<div class="flex items-center gap-2">
<span class="w-2.5 h-2.5 rounded-full bg-warning"></span>
<span>Backups</span>
</div>
<span class="font-medium">5.2 GB</span>
</div>
<div class="flex items-center justify-between text-sm">
<div class="flex items-center gap-2">
<span class="w-2.5 h-2.5 rounded-full bg-base-300"></span>
<span>Other</span>
</div>
<span class="font-medium">2.5 GB</span>
</div>
</div>
<button class="btn color-primary mt-4 w-full">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
Download Database Backup
</button>
</div>
</div> Requires: ux.min.css
<div class="bg-base-100 border border-base-300 rounded-box p-5" style="max-width: 360px;">
<div class="flex items-center gap-3 mb-4">
<div class="flex items-center justify-center w-10 h-10 rounded-field bg-primary/10">
<svg class="size-5 text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"/><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"/></svg>
</div>
<div>
<p class="text-xs text-base-content/50 uppercase font-semibold">Disk Usage</p>
<p class="text-lg font-bold">Storage</p>
</div>
</div>
<div class="w-full h-3 bg-base-200 rounded-full overflow-hidden mb-2">
<div class="h-full rounded-full bg-primary" style="width: 68%;"></div>
</div>
<div class="flex items-center justify-between text-sm mb-4">
<span class="font-semibold">68.2 GB used</span>
<span class="text-base-content/50">of 100 GB</span>
</div>
<div class="flex flex-col gap-2 text-sm">
<div class="flex items-center justify-between">
<div class="flex items-center gap-2"><span class="w-2.5 h-2.5 rounded-full bg-primary"></span>Database</div>
<span class="font-medium">42.1 GB</span>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center gap-2"><span class="w-2.5 h-2.5 rounded-full bg-info"></span>Media</div>
<span class="font-medium">18.4 GB</span>
</div>
</div>
</div> Requires: tw.min.css
// Load storage info via HTMX:
// <div hx-get="/api/storage-info" hx-trigger="load" hx-swap="innerHTML">
// Or poll every 30s:
// hx-trigger="load, every 30s" Upload with Drag & Drop
Preview
Drop files here or browse
Max file size: 50MB
quarterly-report.xlsx
3.8 MB45%
invoice-001.pdf
1.2 MBComplete
<div class="upload mb-4">
<div class="upload-dropzone">
<input type="file" class="upload-input" id="fm-upload" multiple>
<div class="upload-icon">
<svg xmlns="http://www.w3.org/2000/svg" class="size-12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"/></svg>
</div>
<p class="upload-text">Drop files here or <span class="upload-browse" onclick="document.getElementById('fm-upload').click()">browse</span></p>
<p class="upload-hint">Max file size: 50MB</p>
</div>
</div>
<div class="upload-files">
<div class="upload-file">
<div class="upload-preview">
<svg xmlns="http://www.w3.org/2000/svg" class="upload-preview-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
</div>
<div class="upload-file-info">
<div class="upload-file-name">quarterly-report.xlsx</div>
<div class="upload-file-meta"><span>3.8 MB</span><span>45%</span></div>
<div class="upload-progress"><div class="upload-progress-bar" style="width: 45%;"></div></div>
</div>
</div>
<div class="upload-file upload-file-success">
<div class="upload-preview">
<svg xmlns="http://www.w3.org/2000/svg" class="upload-preview-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
</div>
<div class="upload-file-info">
<div class="upload-file-name">invoice-001.pdf</div>
<div class="upload-file-meta"><span>1.2 MB</span><span>Complete</span></div>
</div>
<div class="upload-file-actions">
<button class="upload-file-action upload-file-action-danger">
<svg xmlns="http://www.w3.org/2000/svg" class="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
</button>
</div>
</div>
</div> Requires: ux.min.css
<div class="flex flex-col items-center justify-center min-h-[160px] p-8 bg-base-100 border-2 border-dashed border-base-300 rounded-box cursor-pointer hover:border-primary transition-colors mb-4">
<svg class="size-10 mb-3 text-base-content/40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12"/></svg>
<p class="text-sm font-medium text-base-content">Drop files here or <span class="text-primary cursor-pointer hover:underline">browse</span></p>
<p class="text-xs text-base-content/50 mt-1">Max file size: 50MB</p>
</div>
<div class="flex flex-col gap-2">
<div class="flex items-center gap-3 px-3 py-2 border border-base-300 rounded-field">
<svg class="size-5 text-base-content/40 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/></svg>
<div class="flex-1 min-w-0">
<div class="text-sm font-medium truncate">quarterly-report.xlsx</div>
<div class="text-xs text-base-content/50">3.8 MB · 45%</div>
<div class="w-full h-1 bg-base-200 rounded-sm mt-1 overflow-hidden"><div class="h-full bg-primary rounded-sm" style="width: 45%;"></div></div>
</div>
</div>
</div> Requires: tw.min.css
// Handle file upload with progress:
// const formData = new FormData();
// formData.append('file', file);
// const xhr = new XMLHttpRequest();
// xhr.upload.onprogress = (e) => {
// const pct = (e.loaded / e.total) * 100;
// progressBar.style.width = pct + '%';
// };
// xhr.open('POST', '/api/upload');
// xhr.send(formData);