diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-06 20:46:39 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-06 20:46:39 +0200 |
| commit | 37225762109ad8d11e073f8661359860d678f84a (patch) | |
| tree | 45ff4cb1fb2c244c5ed144bd41268c5e23dfd0fc /packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js | |
| parent | 6c71341422712aee3d4271ecf805146396b9d0e2 (diff) | |
| download | meshbay-37225762109ad8d11e073f8661359860d678f84a.tar.gz | |
fix(client): the folder picker had no background, and its field no layout
Two defects from one screenshot, and a test for the class behind the first.
**The modal was transparent.** `.ftp-panel` asked for `var(--bg-panel,
var(--bg))` and this stylesheet defines neither — the palette is `--bg-base`,
`--bg-surface`, `--bg-raised`. An unknown custom property makes the whole
declaration invalid while the rule around it still applies, so the panel simply
had no background and the page showed straight through it. Three more of mine
were the same: `--bg-hover`, `--bg-input`, `--danger`.
**The field had no layout.** It was built on `.settings-row`, which is
`display:flex; justify-content:space-between` — so a label, a hint and a value
inside one end up spread across a single line in source order, which is how it
read as three unrelated fragments per app. It is its own block now, and the
chosen folders are a table borrowing `.shared-dirs-tbl`: these are lists, and a
wrapped run of chips gives nothing to scan and nowhere to put a per-row remove.
The operator is looking at two lists of directories on one page and they should
read alike.
`test_css_variables.py` is the general form. CSS fails silently and generously
here, and nothing checked. It found four more that predate this branch: the
unread-count badge (`--danger`) had white text on nothing, a transfer link had
no colour, a notification card had no rounding and no unread marker. Fixed, and
`--warn` and `--accent-bg` are promoted from literal fallbacks to real palette
entries at exactly their current light values.
Two of its own regexes were wrong before they were right — a scoped definition
written inline, and one preceded by a comment, were both reported as undefined.
A third check comparing the two palettes fired on `--border-focus`, a focus
ring the themes share deliberately; a heuristic that has to be explained away
on its first run is worse than no test, so it is gone rather than exempted.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011pvMdvLBG92jyhvD5pD6us
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js | 66 |
1 files changed, 54 insertions, 12 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js b/packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js index 1af6573..6e6dfad 100644 --- a/packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js +++ b/packages/meshbay-hub/src/meshbay_hub/static/folder-tree.js @@ -215,8 +215,19 @@ function FolderTreePicker({ } /** - * The button-plus-modal pairing every settings pane wants, so none of them - * has to hold `open` state of its own. + * The chosen folders, as a table, plus the button that opens the picker. + * + * Not a `.settings-row`: that class is `display:flex; justify-content: + * space-between`, so a label, a hint and a value laid out inside one end up + * spread across a single line in whatever order they were written — which is + * how the first version of this read as three unrelated fragments per app. + * + * A table rather than a row of chips because these are lists now. Videos and + * Music can hold several folders, Photos routinely does, and a wrapped run of + * chips gives no column to scan and nowhere to put a per-row control. One + * folder per line, removable where it sits, in the same shape as the shared + * directories table above it — the operator is looking at two lists of + * directories on one page and they should read alike. */ function FolderPickerField({ label, hint, roots, dirs, mode = 'single', requireWritable = false, @@ -226,21 +237,52 @@ function FolderPickerField({ const multi = mode === 'multi'; const chosen = multi ? (value || []) : (value ? [value] : []); + const removeAt = (path) => { + if (!multi) { onChange(''); return; } + onChange(chosen.filter((p) => p !== path)); + }; + return html` - <div class="settings-row"> - <label class="settings-label">${label}</label> - ${hint && html`<p class="settings-hint">${hint}</p>`} - <div class="ftp-field"> - <div class="ftp-field-value"> - ${chosen.length - ? chosen.map((p) => html`<code key=${p} class="ftp-chip">${p}</code>`) - : html`<span class="settings-hint">${t('folder_tree.nothing_selected')}</span>`} - </div> + <div class="folder-field"> + <div class="folder-field-head"> + <h4 class="folder-field-label">${label}</h4> + ${hint && html`<p class="settings-hint">${hint}</p>`} + </div> + + ${chosen.length > 0 && html` + <table class="shared-dirs-tbl folder-field-tbl"> + <tbody> + ${chosen.map((path) => html` + <tr key=${path}> + <td class="sdt-col-dir"> + <span class="sdt-dir-name"> + <${Icon} name="folder" /> + ${path} + </span> + </td> + <td class="sdt-col-actions"> + <button class="sdt-action-btn sdt-action-danger" + disabled=${disabled} + title=${t('folder_tree.remove')} + onClick=${() => removeAt(path)}>\u{2715}</button> + </td> + </tr> + `)} + </tbody> + </table> + `} + + <div class="folder-field-actions"> + ${chosen.length === 0 && html` + <span class="settings-hint">${t('folder_tree.nothing_selected')}</span>`} <button class="btn btn-small btn-secondary" disabled=${disabled} onClick=${() => setOpen(true)}> - <${Icon} name="folder" /> ${t('folder_tree.choose')} + <${Icon} name="folder" /> + ${' '}${chosen.length && multi ? t('folder_tree.add') + : t('folder_tree.choose')} </button> </div> + ${open && html` <${FolderTreePicker} roots=${roots} dirs=${dirs} mode=${mode} |