feat(uxp-panel): fix hover tooltips + add compact list view toggle
Tooltips: the floating .tip-bubble used position:fixed, which UXP's engine does not render reliably, so tooltips never appeared. Switch to position:absolute (body never scrolls, so viewport coords still map), add scroll-offset compensation, and guard against UXP returning 0 for window.innerWidth/innerHeight. List view: add a toolbar toggle (grid vs compact list). List view shows a small 50x28 thumbnail with name/meta and an inline status chip per row, fitting many more clips on screen. Defaults to list, persists via localStorage when the host allows it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3430ef823e
commit
9d8adbbbc1
4 changed files with 77 additions and 5 deletions
|
|
@ -77,6 +77,9 @@
|
|||
<select id="project-filter" class="filter-select" title="Filter by project">
|
||||
<option value="all">All Projects</option>
|
||||
</select>
|
||||
<div id="view-toggle-btn" role="button" tabindex="0" class="iconbtn iconbtn--sm" data-tip="Grid view" data-tip-pos="down-left" aria-label="Toggle layout">
|
||||
<svg width="15" height="15" viewBox="0 0 24 24"><path fill="currentColor" d="M4 11h5V5H4v6zm0 7h5v-6H4v6zm6 0h5v-6h-5v6zm6 0h5v-6h-5v6zm-6-7h5V5h-5v6zm6-6v6h5V5h-5z"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Active sequence info bar -->
|
||||
|
|
|
|||
|
|
@ -28,6 +28,29 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Asset layout toggle: compact list (default) vs thumbnail grid. Persisted
|
||||
// in localStorage when available (UXP host permitting), else session-only.
|
||||
const GRID_ICON = '<svg width="15" height="15" viewBox="0 0 24 24"><path fill="currentColor" d="M4 11h5V5H4v6zm0 7h5v-6H4v6zm6 0h5v-6h-5v6zm6 0h5v-6h-5v6zm-6-7h5V5h-5v6zm6-6v6h5V5h-5z"/></svg>';
|
||||
const LIST_ICON = '<svg width="15" height="15" viewBox="0 0 24 24"><path fill="currentColor" d="M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z"/></svg>';
|
||||
let _viewMode = null;
|
||||
function getViewMode() {
|
||||
if (_viewMode) return _viewMode;
|
||||
try { _viewMode = localStorage.getItem('df_view_mode'); } catch (e) {}
|
||||
return _viewMode || 'list';
|
||||
}
|
||||
function applyViewMode(mode) {
|
||||
_viewMode = mode === 'grid' ? 'grid' : 'list';
|
||||
try { localStorage.setItem('df_view_mode', _viewMode); } catch (e) {}
|
||||
const isList = _viewMode === 'list';
|
||||
document.querySelectorAll('.asset-grid').forEach(g => g.classList.toggle('list-view', isList));
|
||||
const btn = $('view-toggle-btn');
|
||||
if (btn) {
|
||||
// Show the icon for the layout a click switches TO.
|
||||
btn.innerHTML = isList ? GRID_ICON : LIST_ICON;
|
||||
btn.setAttribute('data-tip', isList ? 'Grid view' : 'List view');
|
||||
}
|
||||
}
|
||||
|
||||
function syncConnectBtn() {
|
||||
$('connect-btn').disabled = !$('server-url').value.trim() || !$('api-token').value.trim();
|
||||
}
|
||||
|
|
@ -96,6 +119,11 @@
|
|||
$('tab-library').addEventListener('click', () => Library.switchTab('library'));
|
||||
$('tab-growing').addEventListener('click', () => Library.switchTab('growing'));
|
||||
|
||||
const vt = $('view-toggle-btn');
|
||||
if (vt) vt.addEventListener('click', () => {
|
||||
applyViewMode(getViewMode() === 'list' ? 'grid' : 'list');
|
||||
});
|
||||
|
||||
let searchTimer;
|
||||
$('search-input').addEventListener('input', e => {
|
||||
clearTimeout(searchTimer);
|
||||
|
|
@ -488,6 +516,7 @@
|
|||
|
||||
function init() {
|
||||
enableDivDisabled();
|
||||
applyViewMode(getViewMode());
|
||||
wireConnectPane(); wireLibraryPane();
|
||||
wireExportPanel(); wireConformPanel(); wireRelinkPanel();
|
||||
showVersion();
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@
|
|||
|
||||
const r = el.getBoundingClientRect();
|
||||
const t = tip.getBoundingClientRect();
|
||||
// position:absolute on a body-level node is offset from the document
|
||||
// origin; add scroll offset (0 in practice, body doesn't scroll) for safety.
|
||||
const sx = window.pageXOffset || document.documentElement.scrollLeft || 0;
|
||||
const sy = window.pageYOffset || document.documentElement.scrollTop || 0;
|
||||
const gap = 7;
|
||||
const pos = el.getAttribute('data-tip-pos') || 'down';
|
||||
let x, y;
|
||||
|
|
@ -42,11 +46,12 @@
|
|||
x = r.left + (r.width - t.width) / 2; y = r.bottom + gap;
|
||||
}
|
||||
|
||||
const vw = window.innerWidth, vh = window.innerHeight;
|
||||
const vw = window.innerWidth || document.documentElement.clientWidth || 99999;
|
||||
const vh = window.innerHeight || document.documentElement.clientHeight || 99999;
|
||||
x = Math.max(4, Math.min(x, vw - t.width - 4));
|
||||
y = Math.max(4, Math.min(y, vh - t.height - 4));
|
||||
tip.style.left = x + 'px';
|
||||
tip.style.top = y + 'px';
|
||||
tip.style.left = (x + sx) + 'px';
|
||||
tip.style.top = (y + sy) + 'px';
|
||||
tip.style.opacity = '1';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -454,6 +454,38 @@ input[type="search"]::-webkit-search-cancel-button { display: none; }
|
|||
.status-ready { background: var(--success); color: #06120d; }
|
||||
.status-error { background: var(--danger); color: #fff; }
|
||||
|
||||
/* ── compact list view (toolbar toggle) ─────────────────────────── */
|
||||
.asset-grid.list-view { gap: 2px; padding: 6px 8px; }
|
||||
.asset-grid.list-view .asset-card {
|
||||
flex: 1 1 100%;
|
||||
max-width: 100%;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 9px;
|
||||
padding: 3px 8px 3px 3px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.asset-grid.list-view .asset-thumb,
|
||||
.asset-grid.list-view .asset-thumb-placeholder {
|
||||
width: 50px;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.asset-grid.list-view .asset-thumb-placeholder { font-size: 0; }
|
||||
.asset-grid.list-view .asset-info {
|
||||
order: 1;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
gap: 1px;
|
||||
}
|
||||
.asset-grid.list-view .asset-status {
|
||||
order: 2;
|
||||
position: static;
|
||||
margin-left: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ── action dock ────────────────────────────────────────────────── */
|
||||
.dock {
|
||||
flex-shrink: 0;
|
||||
|
|
@ -606,8 +638,11 @@ input[type="search"]::-webkit-search-cancel-button { display: none; }
|
|||
|
||||
/* ── hover tooltip bubble (driven by src/tooltip.js) ────────────── */
|
||||
.tip-bubble {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
/* UXP's engine does not reliably support position:fixed; absolute on a
|
||||
body-level node maps to the same coords because the panel body never
|
||||
scrolls (only .asset-grid scrolls internally). */
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
white-space: nowrap;
|
||||
|
|
|
|||
Loading…
Reference in a new issue