mirror of
https://github.com/multipleof4/octopus-file-browser.git
synced 2026-09-25 12:35:25 +00:00
Remove demo status line, document context menu, release 0.2.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -58,12 +58,36 @@ Directories are sorted before files. Names use natural, case-insensitive sorting
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `browser.entries` | Gets or replaces the current directory's entries. |
|
| `browser.entries` | Gets or replaces the current directory's entries. |
|
||||||
| `browser.path` | Gets or sets the current directory path, for example `['home', 'ubuntu']`. `..` is shown when it is not empty. |
|
| `browser.path` | Gets or sets the current directory path, for example `['home', 'ubuntu']`. `..` is shown when it is not empty. |
|
||||||
|
| `browser.contextMenu` | Gets or sets the context menu items. Empty by default. |
|
||||||
| `empty-label` | Attribute controlling the empty-directory message. |
|
| `empty-label` | Attribute controlling the empty-directory message. |
|
||||||
| `octopus:open` | Event with `{ entry, path }` when a file is selected. |
|
| `octopus:open` | Event with `{ entry, path }` when a file is selected. |
|
||||||
| `octopus:navigate` | Event with `{ path }` when a directory or `..` is selected. The browser does not change until your app sets `path` and `entries`. |
|
| `octopus:navigate` | Event with `{ path }` when a directory or `..` is selected. The browser does not change until your app sets `path` and `entries`. |
|
||||||
|
|
||||||
The package also exports `OctopusFileBrowser`, `createOctopusFileBrowser`, `sortEntries`, `formatFileSize`, `formatRelativeDate`, `isRecent`, and `fileKindLabel`. Type declarations are included.
|
The package also exports `OctopusFileBrowser`, `createOctopusFileBrowser`, `sortEntries`, `formatFileSize`, `formatRelativeDate`, `isRecent`, and `fileKindLabel`. Type declarations are included.
|
||||||
|
|
||||||
|
## Context menu
|
||||||
|
|
||||||
|
The context menu is off until you set items. Right-click, the Menu key, or a touch long press on a file or directory opens it.
|
||||||
|
|
||||||
|
```js
|
||||||
|
browser.contextMenu = [
|
||||||
|
{ label: 'Copy path', action: (entry, path) => navigator.clipboard.writeText('/' + path.join('/')) },
|
||||||
|
{ label: 'New folder…', when: (entry) => entry.type === 'directory', action: (entry, path) => createFolder(path) },
|
||||||
|
{ label: 'Download', when: (entry) => entry.type === 'file', action: (entry, path) => download(path) },
|
||||||
|
{ label: 'Validate JSON', when: (entry) => entry.name.endsWith('.json'), action: (entry, path) => validate(path) },
|
||||||
|
{ label: 'Delete', danger: true, action: (entry, path) => remove(path) },
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `label` | `string` | Menu item text. |
|
||||||
|
| `action` | `(entry, path) => void` | Called when the item is selected. |
|
||||||
|
| `when` | `(entry, path) => boolean` | Optional. Shows the item only for entries it returns `true` for. Items without `when` show for every entry. |
|
||||||
|
| `danger` | `boolean` | Optional. Styles the item as destructive. |
|
||||||
|
|
||||||
|
Items appear in the order given. When no item matches an entry, the native context menu is shown instead.
|
||||||
|
|
||||||
## Theme
|
## Theme
|
||||||
|
|
||||||
Set CSS custom properties on the element:
|
Set CSS custom properties on the element:
|
||||||
@@ -77,6 +101,7 @@ octopus-file-browser {
|
|||||||
--ofb-hover: #f6f8fa;
|
--ofb-hover: #f6f8fa;
|
||||||
--ofb-focus: #0969da;
|
--ofb-focus: #0969da;
|
||||||
--ofb-recent: #d15700;
|
--ofb-recent: #d15700;
|
||||||
|
--ofb-danger: #cf222e;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
|||||||
:root{color:#181c21;font-synthesis:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}body{min-width:280px;margin:0}main{max-width:1220px;margin:0 auto;padding:20px}@media (width<=640px){main{padding:8px}}.demo-status{color:#57606a;min-height:20px;margin:8px 2px 0;font-size:13px}
|
:root{color:#181c21;font-synthesis:none;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}body{min-width:280px;margin:0}main{max-width:1220px;margin:0 auto;padding:20px}@media (width<=640px){main{padding:8px}}
|
||||||
+2
-3
@@ -6,13 +6,12 @@
|
|||||||
<meta name="color-scheme" content="light">
|
<meta name="color-scheme" content="light">
|
||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
<title>octopus-file-browser</title>
|
<title>octopus-file-browser</title>
|
||||||
<script type="module" crossorigin src="/assets/index-BJSID0yX.js"></script>
|
<script type="module" crossorigin src="/assets/index-DfcMjrKO.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-Bx92WdqS.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-rQJBLWWV.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<octopus-file-browser></octopus-file-browser>
|
<octopus-file-browser></octopus-file-browser>
|
||||||
<p class="demo-status" role="status">Right-click or long-press a file or folder.</p>
|
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
<body>
|
<body>
|
||||||
<main>
|
<main>
|
||||||
<octopus-file-browser></octopus-file-browser>
|
<octopus-file-browser></octopus-file-browser>
|
||||||
<p class="demo-status" role="status">Right-click or long-press a file or folder.</p>
|
|
||||||
</main>
|
</main>
|
||||||
<script type="module" src="/src/demo.js"></script>
|
<script type="module" src="/src/demo.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "octopus-file-browser",
|
"name": "octopus-file-browser",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "octopus-file-browser",
|
"name": "octopus-file-browser",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"license": "SEE LICENSE IN LICENSE",
|
"license": "SEE LICENSE IN LICENSE",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"material-icon-theme": "5.38.1",
|
"material-icon-theme": "5.38.1",
|
||||||
|
|||||||
+4
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "octopus-file-browser",
|
"name": "octopus-file-browser",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"description": "A compact, framework-free file browser inspired by Gitea's repository view.",
|
"description": "A compact, framework-free file browser inspired by Gitea's repository view.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/octopus-file-browser.umd.cjs",
|
"main": "./dist/octopus-file-browser.umd.cjs",
|
||||||
@@ -42,7 +42,9 @@
|
|||||||
"homepage": "https://github.com/multipleof4/octopus-file-browser#readme",
|
"homepage": "https://github.com/multipleof4/octopus-file-browser#readme",
|
||||||
"bugs": "https://github.com/multipleof4/octopus-file-browser/issues",
|
"bugs": "https://github.com/multipleof4/octopus-file-browser/issues",
|
||||||
"funding": "https://github.com/sponsors/multipleof4",
|
"funding": "https://github.com/sponsors/multipleof4",
|
||||||
"publishConfig": { "access": "public" },
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"material-icon-theme": "5.38.1",
|
"material-icon-theme": "5.38.1",
|
||||||
"vite": "8.3.0"
|
"vite": "8.3.0"
|
||||||
|
|||||||
@@ -15,10 +15,3 @@ main {
|
|||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
main { padding: 8px; }
|
main { padding: 8px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.demo-status {
|
|
||||||
color: #57606a;
|
|
||||||
font-size: 13px;
|
|
||||||
margin: 8px 2px 0;
|
|
||||||
min-height: 20px;
|
|
||||||
}
|
|
||||||
|
|||||||
+6
-24
@@ -1,10 +1,8 @@
|
|||||||
import './demo.css';
|
import './demo.css';
|
||||||
import { formatFileSize } from './octopus-file-browser.js';
|
import './octopus-file-browser.js';
|
||||||
import tree from 'virtual:octopus-repo-tree';
|
import tree from 'virtual:octopus-repo-tree';
|
||||||
|
|
||||||
const browser = document.querySelector('octopus-file-browser');
|
const browser = document.querySelector('octopus-file-browser');
|
||||||
const status = document.querySelector('.demo-status');
|
|
||||||
const say = (text) => { status.textContent = text; };
|
|
||||||
const pathText = (path) => `/${path.join('/')}`;
|
const pathText = (path) => `/${path.join('/')}`;
|
||||||
const isDirectory = (entry) => entry.type === 'directory';
|
const isDirectory = (entry) => entry.type === 'directory';
|
||||||
|
|
||||||
@@ -34,41 +32,27 @@ browser.contextMenu = [
|
|||||||
when: isDirectory,
|
when: isDirectory,
|
||||||
action: (entry, path) => {
|
action: (entry, path) => {
|
||||||
const name = prompt(`New folder in ${pathText(path)}`)?.trim();
|
const name = prompt(`New folder in ${pathText(path)}`)?.trim();
|
||||||
if (!name) return;
|
if (name) directory(path).push({ name, type: 'directory', modified: new Date().toISOString(), children: [] });
|
||||||
directory(path).push({ name, type: 'directory', modified: new Date().toISOString(), children: [] });
|
|
||||||
say(`Created ${pathText([...path, name])}`);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Download',
|
label: 'Download',
|
||||||
when: (entry) => entry.type === 'file',
|
when: (entry) => entry.type === 'file',
|
||||||
action: (entry, path) => say(`"Download" on ${pathText(path)} (${formatFileSize(entry.size)})`),
|
action: (entry, path) => console.log('Download', pathText(path)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Validate JSON',
|
label: 'Validate JSON',
|
||||||
when: (entry) => entry.type === 'file' && entry.name.toLowerCase().endsWith('.json'),
|
when: (entry) => entry.type === 'file' && entry.name.toLowerCase().endsWith('.json'),
|
||||||
action: (entry, path) => say(`"Validate JSON" on ${pathText(path)}`),
|
action: (entry, path) => console.log('Validate JSON', pathText(path)),
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Copy path',
|
|
||||||
action: async (entry, path) => {
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(pathText(path));
|
|
||||||
say(`Copied ${pathText(path)}`);
|
|
||||||
} catch {
|
|
||||||
say(`Could not copy ${pathText(path)}`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
{ label: 'Copy path', action: (entry, path) => navigator.clipboard?.writeText(pathText(path)).catch(() => {}) },
|
||||||
{
|
{
|
||||||
label: 'Rename…',
|
label: 'Rename…',
|
||||||
action: (entry, path) => {
|
action: (entry, path) => {
|
||||||
const name = prompt(`Rename ${entry.name}`, entry.name)?.trim();
|
const name = prompt(`Rename ${entry.name}`, entry.name)?.trim();
|
||||||
if (!name || name === entry.name) return;
|
if (!name || name === entry.name || list(browser.path).some((sibling) => sibling.name === name)) return;
|
||||||
if (list(browser.path).some((sibling) => sibling.name === name)) return say(`${name} already exists`);
|
|
||||||
stored(path).name = name;
|
stored(path).name = name;
|
||||||
browser.entries = list(browser.path);
|
browser.entries = list(browser.path);
|
||||||
say(`Renamed ${pathText(path)} to ${name}`);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -79,12 +63,10 @@ browser.contextMenu = [
|
|||||||
const siblings = directory(path.slice(0, -1));
|
const siblings = directory(path.slice(0, -1));
|
||||||
siblings.splice(siblings.indexOf(stored(path)), 1);
|
siblings.splice(siblings.indexOf(stored(path)), 1);
|
||||||
browser.entries = list(browser.path);
|
browser.entries = list(browser.path);
|
||||||
say(`Deleted ${pathText(path)}`);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
browser.addEventListener('octopus:navigate', ({ detail }) => show(detail.path));
|
browser.addEventListener('octopus:navigate', ({ detail }) => show(detail.path));
|
||||||
browser.addEventListener('octopus:open', ({ detail }) => say(`Opened ${pathText(detail.path)}`));
|
|
||||||
|
|
||||||
show([]);
|
show([]);
|
||||||
|
|||||||
Reference in New Issue
Block a user