refactor: simplify queue panel layout and unify tab styling with shared tab components

This commit is contained in:
Dariusz L
2026-06-12 18:42:26 +02:00
parent 406b6b2624
commit 7e6e08a4e7
2 changed files with 82 additions and 77 deletions
+60 -42
View File
@@ -297,19 +297,12 @@
.mr-queue-header {
display: flex;
justify-content: space-between;
justify-content: flex-end;
align-items: center;
gap: var(--mr-spacing-10);
min-height: 44px;
margin-bottom: 0;
padding: 0 0 10px;
}
.mr-queue-title {
color: var(--mr-text, #f3f3f3);
font-size: 14px;
font-weight: 700;
line-height: 1.25;
gap: var(--mr-spacing-6);
min-height: 36px;
margin: 0;
padding: 6px 0 8px;
}
.mr-queue-actions {
@@ -317,46 +310,71 @@
gap: var(--mr-spacing-6);
}
.mr-queue-tabs {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 4px;
margin-bottom: 8px;
padding: 3px;
background: rgba(255, 255, 255, 0.045);
border: 1px solid rgba(255, 255, 255, 0.075);
border-radius: 6px;
.mr-queue-tabs.mr-tabs {
align-self: stretch;
flex: 0 0 auto;
height: 34px;
margin: 0 0 -1px;
padding: 0 4px;
overflow: visible;
background: #1f1f1f;
--mr-tab-active-bg: #111;
--mr-tab-corner-size: 12px;
}
.mr-queue-tab {
.mr-queue-tab.mr-tab {
flex: 1 1 0;
min-width: 0;
height: 28px;
padding: 0 8px;
overflow: hidden;
color: var(--mr-text-muted, #b1b1b1);
font-size: 12px;
height: 32px;
min-height: 32px;
padding: 0 12px 5px;
font-weight: 700;
line-height: 28px;
text-align: center;
}
.mr-queue-tab.mr-tab .mr-tab-label {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
background: transparent;
border: 0;
border-radius: 4px;
cursor: pointer;
}
.mr-queue-tab:hover,
.mr-queue-tab:focus-visible {
color: var(--mr-text, #f3f3f3);
background: rgba(255, 255, 255, 0.06);
outline: none;
.mr-queue-tab.mr-tab:not(.mr-tab-active):hover,
.mr-queue-tab.mr-tab:not(.mr-tab-active):focus,
.mr-queue-tab.mr-tab:not(.mr-tab-active):active {
padding: 0 12px 5px !important;
}
.mr-queue-tab.is-active {
color: #f5fff6;
background: rgba(114, 211, 138, 0.18);
box-shadow: inset 0 0 0 1px rgba(114, 211, 138, 0.24);
.mr-queue-tab.mr-tab:not(.mr-tab-active)::after {
inset: 2px 5px 6px;
}
.mr-queue-tab.mr-tab:not(.mr-tab-active) + .mr-queue-tab.mr-tab:not(.mr-tab-active)::before {
top: 8px;
bottom: 13px;
}
.mr-queue-tab.mr-tab.mr-tab-active {
height: 32px;
min-height: 32px;
padding: 0 12px 5px;
}
.mr-queue-tab.mr-tab.mr-tab-active::before,
.mr-queue-tab.mr-tab.mr-tab-active::after {
width: 12px;
height: 12px;
}
.mr-queue-tab.mr-tab.mr-tab-active::before {
left: -10px;
-webkit-mask: radial-gradient(circle at 0 0, transparent 10px, #000 10px);
mask: radial-gradient(circle at 0 0, transparent 10px, #000 10px);
}
.mr-queue-tab.mr-tab.mr-tab-active::after {
right: -10px;
-webkit-mask: radial-gradient(circle at 100% 0, transparent 10px, #000 10px);
mask: radial-gradient(circle at 100% 0, transparent 10px, #000 10px);
}
.mr-queue-list {
+22 -35
View File
@@ -70,13 +70,6 @@ export const queueMethods = {
createQueuePanel() {
this.queuePanelActiveTab = this.queuePanelActiveTab || 'queued';
this.queueTitle = $el("div#queue-title.mr-queue-title", { textContent: "Queued Selections (0)" });
this.queueToggleButton = $el("button", {
id: "queue-toggle",
className: "mr-btn mr-btn-secondary mr-btn-sm",
textContent: "Collapse",
onclick: () => this.toggleQueueCollapsed()
});
this.queueClearButton = $el("button", {
id: "queue-clear",
className: "mr-btn mr-btn-secondary mr-btn-sm",
@@ -84,21 +77,19 @@ export const queueMethods = {
onclick: () => this.clearAllQueued()
});
this.queueQueuedTabButton = $el("button.mr-queue-tab.is-active", {
this.queueQueuedTabButton = $el("button.mr-tab.mr-queue-tab.mr-tab-active", {
type: "button",
"data-tab": "queued",
role: "tab",
textContent: "Queued (0)",
onclick: () => this.setQueuePanelTab('queued')
});
this.queueDownloadsTabButton = $el("button.mr-queue-tab", {
}, [$el("span.mr-tab-label", { textContent: "Queued (0)" })]);
this.queueDownloadsTabButton = $el("button.mr-tab.mr-queue-tab", {
type: "button",
"data-tab": "downloads",
role: "tab",
textContent: "Downloads (0)",
onclick: () => this.setQueuePanelTab('downloads')
});
this.queueTabs = $el("div.mr-queue-tabs", {
}, [$el("span.mr-tab-label", { textContent: "Downloads (0)" })]);
this.queueTabs = $el("div.mr-tabs.mr-queue-tabs", {
role: "tablist",
"aria-label": "Queue panel views"
}, [
@@ -106,20 +97,15 @@ export const queueMethods = {
this.queueDownloadsTabButton
]);
// Header row with title and clear button
this.queueHeader = $el("div.mr-queue-header", {}, [
this.queueTitle,
$el("div.mr-queue-actions", {}, [
this.queueToggleButton,
this.queueClearButton
])
this.queueClearButton
]);
// Scrollable list
this.queueList = $el("div#queue-list.mr-queue-list");
const panel = $el("div.mr-queue-panel", {}, [
$el("div.mr-queue-stack", {}, [this.queueHeader, this.queueTabs, this.queueList])
$el("div.mr-queue-stack", {}, [this.queueTabs, this.queueHeader, this.queueList])
]);
return panel;
},
@@ -136,17 +122,10 @@ export const queueMethods = {
const list = Array.isArray(this.pendingResolutions) ? this.pendingResolutions : [];
const downloads = this.getActiveQueuePanelDownloads();
const activeTab = this.queuePanelActiveTab === 'downloads' ? 'downloads' : 'queued';
// Update title count
const title = this.queueTitle || this.queueHeader.querySelector('#queue-title');
if (title) {
title.textContent = activeTab === 'downloads'
? `Downloads (${downloads.length})`
: `Queued Selections (${list.length})`;
}
const toggleBtn = this.queueToggleButton || this.queueHeader.querySelector('#queue-toggle');
if (toggleBtn) toggleBtn.textContent = this.queueCollapsed ? 'Expand' : 'Collapse';
const clearBtn = this.queueClearButton || this.queueHeader.querySelector('#queue-clear');
if (clearBtn) clearBtn.style.display = activeTab === 'queued' ? '' : 'none';
const showActions = activeTab === 'queued';
this.queueHeader.style.display = showActions ? '' : 'none';
if (clearBtn) clearBtn.style.display = showActions ? '' : 'none';
this.updateQueuePanelTabs(list.length, downloads.length, activeTab);
if (activeTab === 'downloads') {
@@ -160,14 +139,22 @@ export const queueMethods = {
updateQueuePanelTabs(queueCount, downloadCount, activeTab) {
const queuedTab = this.queueQueuedTabButton || this.queueTabs?.querySelector?.('.mr-queue-tab[data-tab="queued"]');
const downloadsTab = this.queueDownloadsTabButton || this.queueTabs?.querySelector?.('.mr-queue-tab[data-tab="downloads"]');
const setTabLabel = (tab, label) => {
const labelEl = tab?.querySelector?.('.mr-tab-label');
if (labelEl) {
labelEl.textContent = label;
} else if (tab) {
tab.textContent = label;
}
};
if (queuedTab) {
queuedTab.textContent = `Queued (${queueCount})`;
queuedTab.classList.toggle('is-active', activeTab === 'queued');
setTabLabel(queuedTab, `Queued (${queueCount})`);
queuedTab.classList.toggle('mr-tab-active', activeTab === 'queued');
queuedTab.setAttribute('aria-selected', activeTab === 'queued' ? 'true' : 'false');
}
if (downloadsTab) {
downloadsTab.textContent = `Downloads (${downloadCount})`;
downloadsTab.classList.toggle('is-active', activeTab === 'downloads');
setTabLabel(downloadsTab, `Downloads (${downloadCount})`);
downloadsTab.classList.toggle('mr-tab-active', activeTab === 'downloads');
downloadsTab.setAttribute('aria-selected', activeTab === 'downloads' ? 'true' : 'false');
}
},