feat: enhance pop-out viewer UI for node details with improved styling, icons, and layout.

This commit is contained in:
AEmotionStudio
2026-01-05 23:47:12 -08:00
parent 88a04b117e
commit d13fb7de56
4 changed files with 114 additions and 14 deletions
+1 -1
View File
@@ -101,7 +101,7 @@ export class PopOutManager {
*/
private getViewerUrl(): string {
// Cache-busting version - increment to force refresh
const version = 'v21';
const version = 'v22';
// Find the extension's base URL from the loaded scripts
const scripts = document.querySelectorAll('script[src*="magnify"]');
+1 -1
View File
@@ -28,7 +28,7 @@ class PopOutManager {
* Get the URL for the pop-out viewer page.
*/
getViewerUrl() {
const version = "v21";
const version = "v22";
const scripts = document.querySelectorAll('script[src*="magnify"]');
Logger.debug(`[PopOut] Found ${scripts.length} magnify scripts`);
if (scripts.length > 0) {
File diff suppressed because one or more lines are too long
+111 -11
View File
@@ -1196,21 +1196,121 @@
function renderList(title, items) {
if (!items || items.length === 0) return '';
const listHtml = items.map(item => {
const name = escapeHtml(item.name || item.label || 'Unknown');
const type = item.type ? `<span style="opacity:0.6; font-size:10px; margin-left:4px">(${escapeHtml(item.type)})</span>` : '';
const value = item.value !== undefined ? `<span style="opacity:0.8; margin-left:auto">${escapeHtml(String(item.value))}</span>` : '';
// Icon mapping for different list types
const icons = {
'Inputs': `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"/><polyline points="10 17 15 12 10 7"/><line x1="15" y1="12" x2="3" y2="12"/></svg>`,
'Outputs': `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>`,
'Widgets': `<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>`
};
const icon = icons[title] || '';
return `<div style="display:flex; justify-content:space-between; padding:2px 0; font-size:11px; color:var(--text-secondary);">
<span>- ${name}${type}</span>
${value}
</div>`;
// Gradient colors for different types
const gradients = {
'Inputs': 'linear-gradient(135deg, rgba(59, 130, 246, 0.15), rgba(59, 130, 246, 0.05))',
'Outputs': 'linear-gradient(135deg, rgba(34, 197, 94, 0.15), rgba(34, 197, 94, 0.05))',
'Widgets': 'linear-gradient(135deg, rgba(168, 85, 247, 0.15), rgba(168, 85, 247, 0.05))'
};
const gradient = gradients[title] || 'linear-gradient(135deg, rgba(100, 100, 100, 0.15), rgba(100, 100, 100, 0.05))';
// Badge colors for different types
const badgeColors = {
'Inputs': '#3b82f6',
'Outputs': '#22c55e',
'Widgets': '#a855f7'
};
const badgeColor = badgeColors[title] || '#888';
const listHtml = items.map((item, index) => {
const name = escapeHtml(item.name || item.label || 'Unknown');
const type = item.type ? escapeHtml(item.type) : null;
const value = item.value !== undefined ? escapeHtml(String(item.value)) : null;
return `
<div style="
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 10px;
background: var(--bg-secondary);
border-radius: 6px;
margin-bottom: 4px;
border: 1px solid var(--border-subtle);
transition: all 0.15s ease;
" onmouseover="this.style.background='var(--bg-tertiary)'; this.style.borderColor='var(--border-default)'"
onmouseout="this.style.background='var(--bg-secondary)'; this.style.borderColor='var(--border-subtle)'">
<div style="display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0;">
<span style="
font-size: 11px;
font-weight: 500;
color: var(--text-primary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
">${name}</span>
${type ? `<span style="
font-size: 9px;
padding: 2px 6px;
background: ${badgeColor}22;
color: ${badgeColor};
border-radius: 4px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.3px;
flex-shrink: 0;
">${type}</span>` : ''}
</div>
${value ? `<span style="
font-size: 11px;
color: var(--accent-blue);
font-weight: 500;
background: var(--accent-blue)11;
padding: 2px 8px;
border-radius: 4px;
margin-left: 8px;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex-shrink: 0;
">${value}</span>` : ''}
</div>`;
}).join('');
return `
<div class="info-row" style="display:block; border-top:1px solid var(--border-subtle); margin-top:8px; padding-top:8px;">
<div style="font-weight:600; font-size:11px; margin-bottom:4px; color:var(--text-primary); opacity:0.8;">${title} (${items.length})</div>
<div style="padding-left:4px;">${listHtml}</div>
<div style="
margin-top: 12px;
border-radius: 8px;
overflow: hidden;
border: 1px solid var(--border-default);
background: var(--bg-primary);
">
<div style="
display: flex;
align-items: center;
gap: 8px;
padding: 10px 12px;
background: ${gradient};
border-bottom: 1px solid var(--border-subtle);
">
<span style="color: ${badgeColor}; display: flex; align-items: center;">${icon}</span>
<span style="
font-weight: 600;
font-size: 12px;
color: var(--text-primary);
">${title}</span>
<span style="
font-size: 10px;
padding: 2px 8px;
background: ${badgeColor}33;
color: ${badgeColor};
border-radius: 10px;
font-weight: 600;
margin-left: auto;
">${items.length}</span>
</div>
<div style="padding: 8px;">
${listHtml}
</div>
</div>
`;
}