ui(uxp): v2.2.0 — density pass: drop details panel, tighter buttons, collapsible Advanced

User feedback after v2.1.9: panel still chrome-heavy. The Asset Info
panel duplicates what the card already shows; 8 buttons across 3
full-width rows still claim too much vertical real estate.

Three surgical changes:

1. Drop the Asset Info details panel entirely. Card meta (name +
   duration + codec) already carries everything we showed in the
   key:value table. Library._showDetails / hideDetails become no-ops
   so the existing call sites in main.js + library.js don't need
   conditional branches.

2. Shrink .action-row .btn to 20px tall, 10.5px font, 6px horiz
   padding, 3px radius. Two rows of compact buttons fit where one
   bulky row used to.

3. Collapse Advanced section behind a toggle (▸ / ▾). Default
   collapsed so the main 6 buttons stay the primary action surface;
   click the row to expand and reveal Export & Conform / Fetch &
   Relink All.

Per DESIGN.md "density over whitespace."

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Claude 2026-05-28 13:03:56 -04:00
parent c3b087020d
commit e4e69973e5
5 changed files with 66 additions and 53 deletions

View file

@ -89,17 +89,10 @@
</div>
</div>
<!-- Asset details panel -->
<div id="details-panel" class="details-panel hidden">
<div class="details-header">Asset Info</div>
<div class="details-row"><span class="dl">Filename</span><span id="d-filename" class="dv"></span></div>
<div class="details-row"><span class="dl">Codec</span><span id="d-codec" class="dv"></span></div>
<div class="details-row"><span class="dl">Resolution</span><span id="d-res" class="dv"></span></div>
<div class="details-row"><span class="dl">FPS</span><span id="d-fps" class="dv"></span></div>
<div class="details-row"><span class="dl">Duration</span><span id="d-dur" class="dv"></span></div>
<div class="details-row"><span class="dl">Size</span><span id="d-size" class="dv"></span></div>
<div class="details-row"><span class="dl">Tags</span><div id="d-tags" class="tags-row"></div></div>
</div>
<!-- (v2.2.0) Asset details panel dropped — card meta already carries
name / codec / duration. If we need richer detail later, surface
it on the card hover state rather than reserving permanent space. -->
<div id="details-panel" class="hidden"></div>
<!-- Action buttons -->
<footer class="actions">
@ -126,12 +119,17 @@
<div id="toast" class="toast hidden"></div>
</footer>
<!-- Advanced section -->
<!-- Advanced section — collapsed by default; click the row to expand. -->
<div class="advanced-section">
<div class="advanced-title">Advanced</div>
<div class="action-row">
<button id="export-conform-btn" class="btn btn-secondary btn-sm" disabled>Export &amp; Conform</button>
<button id="fetch-relink-btn" class="btn btn-secondary btn-sm" disabled>Fetch &amp; Relink All</button>
<button id="advanced-toggle" class="advanced-toggle" type="button" aria-expanded="false">
<span class="advanced-caret"></span>
<span class="advanced-title">Advanced</span>
</button>
<div id="advanced-body" class="advanced-body hidden">
<div class="action-row">
<button id="export-conform-btn" class="btn btn-secondary" disabled>Export &amp; Conform</button>
<button id="fetch-relink-btn" class="btn btn-secondary" disabled>Fetch &amp; Relink All</button>
</div>
</div>
</div>
</section>

View file

@ -2,7 +2,7 @@
"manifestVersion": 5,
"id": "net.wilddragon.dragonflight.uxp",
"name": "Dragonflight MAM",
"version": "2.1.9",
"version": "2.2.0",
"main": "index.html",
"host": {
"app": "premierepro",

View file

@ -199,32 +199,15 @@
};
Library.hideDetails = function () {
// v2.2.0: details panel dropped — clearing selection is enough.
Library.state.selectedId = null;
document.getElementById('details-panel').classList.add('hidden');
Library._syncActions();
};
Library._showDetails = function (asset) {
const p = document.getElementById('details-panel');
p.classList.remove('hidden');
document.getElementById('d-filename').textContent = asset.display_name || asset.filename || '—';
document.getElementById('d-codec').textContent = asset.codec || asset.media_type || '—';
document.getElementById('d-res').textContent = asset.resolution || '—';
document.getElementById('d-fps').textContent = asset.fps ? asset.fps + ' fps' : '—';
document.getElementById('d-dur').textContent = asset.duration_ms ? UI.formatDuration(asset.duration_ms / 1000) : '—';
document.getElementById('d-size').textContent = asset.file_size ? UI.formatBytes(Number(asset.file_size)) : '—';
const tagsEl = document.getElementById('d-tags');
tagsEl.innerHTML = '';
const tags = asset.tags || [];
if (tags.length) {
tags.forEach(t => {
const s = document.createElement('span');
s.className = 'tag'; s.textContent = t;
tagsEl.appendChild(s);
});
} else {
tagsEl.innerHTML = '<span class="muted">—</span>';
}
Library._showDetails = function (_asset) {
// v2.2.0: card already shows display_name / duration / codec, and the
// accent-bordered selected card is the affordance. No-op kept so call
// sites in main.js / library.js don't need branching.
};
Library._syncActions = function () {

View file

@ -184,6 +184,16 @@
$('export-timeline-btn').addEventListener('click', openExportPanel);
$('export-conform-btn').addEventListener('click', openConformPanel);
$('fetch-relink-btn').addEventListener('click', openRelinkPanel);
// Advanced collapsible toggle (v2.2.0).
const advToggle = $('advanced-toggle');
const advBody = $('advanced-body');
if (advToggle && advBody) {
advToggle.addEventListener('click', () => {
const open = advBody.classList.toggle('hidden') === false;
advToggle.setAttribute('aria-expanded', String(open));
});
}
}
function _disableImportBtns(dis) {

View file

@ -460,37 +460,59 @@ input[type="search"]::-webkit-search-cancel-button { display: none; }
gap: 4px;
}
.action-row { display: flex; gap: 4px; }
/* Compact action buttons (v2.1.8 density): 22px tall, smaller type, less
padding. Operators have many actions visible at once shrink the chrome
per DESIGN.md "density over whitespace". */
/* Compact action buttons (v2.2.0): tighter again. 20px tall, 10.5px font,
thinner padding. Two rows fit where one used to. */
.action-row .btn {
flex: 1;
height: 22px;
padding: 0 8px;
font-size: 11px;
height: 20px;
padding: 0 6px;
font-size: 10.5px;
font-weight: 600;
letter-spacing: 0.01em;
white-space: nowrap;
}
.advanced-section .action-row .btn {
height: 20px;
font-size: 10.5px;
border-radius: 3px;
}
/* ── advanced section ────────────────────────────────────────────── */
/* advanced section
v2.2.0: collapsible. The toggle is a tiny full-width strip with a
caret + label; clicking it reveals the action row below. Default
collapsed so the main 6 buttons stay the dominant action surface. */
.advanced-section {
flex-shrink: 0;
border-top: 1px solid var(--border);
padding: 6px 0 8px;
margin-top: 4px;
}
.advanced-toggle {
display: flex;
align-items: center;
gap: 6px;
width: 100%;
padding: 4px 4px;
font: inherit;
background: transparent;
border: none;
border-radius: 3px;
cursor: pointer;
color: var(--text-3);
transition: color var(--t-fast), background var(--t-fast);
}
.advanced-toggle:hover { color: var(--text-2); background: var(--hover); }
.advanced-caret {
display: inline-block;
font-size: 8px;
width: 10px;
text-align: center;
transition: transform var(--t-fast);
}
.advanced-toggle[aria-expanded="true"] .advanced-caret { transform: rotate(90deg); }
.advanced-title {
font-size: 9.5px;
font-weight: 700;
color: var(--text-3);
text-transform: uppercase;
letter-spacing: 0.07em;
margin-bottom: 5px;
}
.advanced-body {
padding: 4px 0 8px;
}
/* ── progress ────────────────────────────────────────────────────── */