-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add severity tooltips in HTML report #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
16d196e
5fee399
0e709db
cfd505c
e289408
a7ab9fb
8d1f9cf
cb6ed8a
b46906a
839ca1b
b15041b
1f9818a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -150,25 +150,29 @@ <h2>Ready to analyze</h2> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="grade-score">' + scores.overall.percentage + ' <span>/ 100</span></div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="grade-label">Overall Score · ' + result.nodeCount + ' nodes</div>'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Category grid | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Category list | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var categories = CanICode.CATEGORIES || CATEGORIES; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var catTips = { structure: 'Can AI read the layout? (Auto Layout, nesting, positioning)', token: 'Can AI reproduce exact values? (colors, fonts, shadows, spacing)', component: 'Is the design efficient for AI context? (reuse, variants)', naming: 'Can AI infer meaning? (semantic names, conventions)', behavior: 'Can AI know what happens? (overflow, truncation, interactions)' }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var gridEl = document.getElementById('cat-grid'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gridEl.innerHTML = categories.map(function(cat) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var cs = scores.byCategory[cat]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return '<div class="cat-card" data-cat="' + cat + '" onclick="filterCategory(\'' + cat + '\')">' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var barColor = cs.percentage >= 80 ? 'var(--green)' : cs.percentage >= 60 ? 'var(--amber)' : 'var(--red)'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return '<div class="cat-row">' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="cat-score ' + scoreClass(cs.percentage) + '">' + cs.percentage + '</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="cat-label">' + (CATEGORY_LABELS[cat] || cat) + '</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="cat-issues">' + cs.issueCount + ' issues</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="cat-label" data-tip="' + esc(catTips[cat] || '') + '">' + (CATEGORY_LABELS[cat] || cat) + '</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="cat-bar"><div class="cat-bar-fill" style="width:' + cs.percentage + '%;background:' + barColor + '"></div></div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="cat-issues">' + cs.issueCount + '</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '</div>'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }).join(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Summary bar | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var s = scores.summary; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var sevTips = { blocking: 'Cannot implement correctly without fixing. Direct impact on screen reproduction.', risk: 'Implementable now but will break or increase cost later.', missing: 'Information is absent, forcing AI to guess.', suggestion: 'Not immediately problematic, but improves systemization.' }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.getElementById('summary-bar').innerHTML = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-item"><span class="dot dot-blocking"></span><span class="summary-count">' + s.blocking + '</span> Blocking</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-item"><span class="dot dot-risk"></span><span class="summary-count">' + s.risk + '</span> Risk</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-item"><span class="dot dot-missing"></span><span class="summary-count">' + s.missingInfo + '</span> Missing</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-item"><span class="dot dot-suggestion"></span><span class="summary-count">' + s.suggestion + '</span> Suggestion</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-item" data-tip="' + esc(sevTips.blocking) + '"><span class="dot dot-blocking"></span><span class="summary-count">' + s.blocking + '</span> Blocking</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-item" data-tip="' + esc(sevTips.risk) + '"><span class="dot dot-risk"></span><span class="summary-count">' + s.risk + '</span> Risk</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-item" data-tip="' + esc(sevTips.missing) + '"><span class="dot dot-missing"></span><span class="summary-count">' + s.missingInfo + '</span> Missing</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-item" data-tip="' + esc(sevTips.suggestion) + '"><span class="dot dot-suggestion"></span><span class="summary-count">' + s.suggestion + '</span> Suggestion</div>' + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| '<div class="summary-total">' + s.totalIssues + ' total</div>'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Filter tabs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -260,10 +264,6 @@ <h2>Ready to analyze</h2> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.querySelectorAll('.filter-tab').forEach(function(tab) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tab.classList.toggle('active', tab.dataset.cat === cat); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Update category card highlights | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.querySelectorAll('.cat-card').forEach(function(card) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| card.classList.toggle('active', card.dataset.cat === cat); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (currentResult) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| renderIssues(currentResult.issues, cat); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -343,6 +343,41 @@ <h2>Ready to analyze</h2> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ---- Tooltip (JS-based, works inside Figma iframe) ---- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (function() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var tip = document.createElement('div'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tip.className = 'cic-tooltip'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var arrow = document.createElement('div'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| arrow.className = 'cic-tooltip-arrow'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.body.appendChild(tip); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.body.appendChild(arrow); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function hide() { tip.classList.remove('visible'); arrow.classList.remove('visible'); } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.addEventListener('mouseover', function(e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var el = e.target.closest('[data-tip]'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!el) { hide(); return; } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tip.textContent = el.getAttribute('data-tip'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tip.classList.add('visible'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var rect = el.getBoundingClientRect(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var tipH = tip.offsetHeight; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var tipW = tip.offsetWidth; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var cx = rect.left + rect.width / 2; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var tipLeft = Math.max(4, Math.min(cx - tipW / 2, window.innerWidth - tipW - 4)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var above = rect.top - tipH - 10 >= 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var tipTop = above ? rect.top - tipH - 10 : rect.bottom + 10; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tip.style.left = tipLeft + 'px'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tip.style.top = tipTop + 'px'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| arrow.style.left = (cx - 4) + 'px'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| arrow.style.top = (above ? rect.top - 14 : rect.bottom + 6) + 'px'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| arrow.classList.add('visible'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.addEventListener('mouseleave', hide); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| document.addEventListener('mouseout', function(e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!e.target.closest('[data-tip]')) hide(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+356
to
+379
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hide the tooltip when the pointer leaves the plugin. The current 🐛 Suggested fix- document.addEventListener('mouseout', function(e) {
- if (!e.target.closest('[data-tip]')) hide();
- });
+ document.addEventListener('mouseout', function(e) {
+ var to = e.relatedTarget && e.relatedTarget.closest ? e.relatedTarget.closest('[data-tip]') : null;
+ if (!to) hide();
+ });
+ document.documentElement.addEventListener('mouseleave', hide);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </script> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </body> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </html> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -154,7 +154,7 @@ <h1 class="text-3xl font-bold tracking-tight">Analyze your Figma designs</h1> | |||||||||
| </section> | ||||||||||
|
|
||||||||||
| <section class="bg-card border border-border rounded-lg shadow-sm p-6 mb-6 fade-in"> | ||||||||||
| <div id="category-gauges" class="grid grid-cols-3 sm:grid-cols-6 gap-4"></div> | ||||||||||
| <div id="category-gauges" class="grid grid-cols-3 sm:grid-cols-5 gap-4"></div> | ||||||||||
| </section> | ||||||||||
|
|
||||||||||
| <section id="summary-section" class="bg-card border border-border rounded-lg shadow-sm p-4 mb-6 fade-in"> | ||||||||||
|
|
@@ -356,9 +356,11 @@ <h2 class="text-sm font-semibold flex items-center gap-2"> | |||||||||
|
|
||||||||||
| document.getElementById('category-gauges').innerHTML = CATEGORIES.map(function(cat) { | ||||||||||
| var cs = scores.byCategory[cat]; | ||||||||||
| var desc = CATEGORY_DESCRIPTIONS[cat]; | ||||||||||
| return '<a href="#cat-' + cat + '" class="flex flex-col items-center group relative cursor-pointer no-underline text-foreground hover:opacity-80 transition-opacity">' + renderGaugeSvg(cs.percentage, 100, 7) + | ||||||||||
| '<span class="text-xs font-medium mt-2.5 text-center leading-tight">' + CATEGORY_LABELS[cat] + '</span>' + | ||||||||||
| '<span class="text-[11px] text-muted-foreground">' + cs.issueCount + ' issues</span></a>'; | ||||||||||
| '<span class="text-[11px] text-muted-foreground">' + cs.issueCount + ' issues</span>' + | ||||||||||
| '<div class="absolute bottom-full mb-2 left-1/2 -translate-x-1/2 hidden group-hover:block bg-zinc-900 text-white text-xs px-3 py-2 rounded-md max-w-[220px] w-max z-10 shadow-lg pointer-events-none">' + esc(desc) + '<div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-900"></div></div></a>'; | ||||||||||
| }).join(''); | ||||||||||
|
|
||||||||||
| document.getElementById('summary-dots').innerHTML = | ||||||||||
|
|
@@ -387,7 +389,8 @@ <h2 class="text-sm font-semibold flex items-center gap-2"> | |||||||||
| document.getElementById('footer-meta').textContent = new Date().toLocaleString() + ' \u00B7 ' + result.nodeCount + ' nodes \u00B7 Max depth ' + result.maxDepth; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| function renderDot(cls, count, label) { return '<div class="flex items-center gap-2"><span class="w-2.5 h-2.5 rounded-full ' + cls + '"></span><span class="text-lg font-bold">' + count + '</span><span class="text-sm text-muted-foreground">' + label + '</span></div>'; } | ||||||||||
| var SEV_TIPS = { Blocking: 'Cannot implement correctly without fixing. Direct impact on screen reproduction.', Risk: 'Implementable now but will break or increase cost later.', 'Missing Info': 'Information is absent, forcing AI to guess.', Suggestion: 'Not immediately problematic, but improves systemization.' }; | ||||||||||
| function renderDot(cls, count, label) { var tip = SEV_TIPS[label] || ''; return '<div class="flex items-center gap-2 relative group cursor-help"><span class="w-2.5 h-2.5 rounded-full ' + cls + '"></span><span class="text-lg font-bold">' + count + '</span><span class="text-sm text-muted-foreground">' + label + '</span><div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 hidden group-hover:block bg-zinc-900 text-white text-xs px-3 py-2 rounded-md max-w-[220px] w-max z-10 shadow-lg pointer-events-none">' + esc(tip) + '<div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-900"></div></div></div>'; } | ||||||||||
|
Comment on lines
+392
to
+393
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a fallback tooltip title in At Line 393, 🛠️ Suggested fix- function renderDot(cls, count, label) { var tip = SEV_TIPS[label] || ''; return '<div class="flex items-center gap-2 relative group cursor-help"><span class="w-2.5 h-2.5 rounded-full ' + cls + '"></span><span class="text-lg font-bold">' + count + '</span><span class="text-sm text-muted-foreground">' + label + '</span><div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 hidden group-hover:block bg-zinc-900 text-white text-xs px-3 py-2 rounded-md max-w-[220px] w-max z-10 shadow-lg pointer-events-none">' + esc(tip) + '<div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-900"></div></div></div>'; }
+ function renderDot(cls, count, label) { var tip = SEV_TIPS[label] || ''; return '<div class="flex items-center gap-2 relative group cursor-help" title="' + esc(tip) + '"><span class="w-2.5 h-2.5 rounded-full ' + cls + '"></span><span class="text-lg font-bold">' + count + '</span><span class="text-sm text-muted-foreground">' + label + '</span><div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 hidden group-hover:block bg-zinc-900 text-white text-xs px-3 py-2 rounded-md max-w-[220px] w-max z-10 shadow-lg pointer-events-none">' + esc(tip) + '<div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-900"></div></div></div>'; }📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| function renderCat(cat, scores, issues, fk) { | ||||||||||
| var cs = scores.byCategory[cat], hp = issues.some(function(i) { return i.config.severity === 'blocking' || i.config.severity === 'risk'; }); | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -122,7 +122,7 @@ ${CATEGORIES.map(cat => { | |
| ${renderGaugeSvg(cs.percentage, 100, 7)} | ||
| <span class="text-xs font-medium mt-2.5 text-center leading-tight">${CATEGORY_LABELS[cat]}</span> | ||
| <span class="text-[11px] text-muted-foreground">${cs.issueCount} issues</span> | ||
| <div class="absolute bottom-full mb-2 left-1/2 -translate-x-1/2 hidden group-hover:block bg-zinc-900 text-white text-xs px-3 py-2 rounded-md whitespace-nowrap z-10 shadow-lg pointer-events-none"> | ||
| <div class="absolute bottom-full mb-2 left-1/2 -translate-x-1/2 hidden group-hover:block bg-zinc-900 text-white text-xs px-3 py-2 rounded-md max-w-[220px] w-max z-10 shadow-lg pointer-events-none"> | ||
| ${esc(desc)} | ||
| <div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-900"></div> | ||
| </div> | ||
|
|
@@ -202,11 +202,20 @@ ${figmaToken ? ` <script> | |
|
|
||
| // ---- Components ---- | ||
|
|
||
| const SEVERITY_TOOLTIPS: Record<string, string> = { | ||
| Blocking: "Cannot implement correctly without fixing. Direct impact on screen reproduction.", | ||
| Risk: "Implementable now but will break or increase cost later.", | ||
| "Missing Info": "Information is absent, forcing AI to guess.", | ||
| Suggestion: "Not immediately problematic, but improves systemization.", | ||
| }; | ||
|
Comment on lines
+205
to
+210
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Move the severity tooltip text into shared constants. These definitions are now duplicated here, in 🤖 Prompt for AI Agents |
||
|
|
||
| function renderSummaryDot(dotClass: string, count: number, label: string): string { | ||
| return `<div class="flex items-center gap-2"> | ||
| const tooltip = SEVERITY_TOOLTIPS[label] ?? ""; | ||
| return `<div class="flex items-center gap-2 relative group cursor-help" title="${escapeHtml(tooltip)}"> | ||
| <span class="w-2.5 h-2.5 rounded-full ${dotClass}"></span> | ||
| <span class="text-lg font-bold tracking-tight">${count}</span> | ||
| <span class="text-sm text-muted-foreground">${label}</span> | ||
| <div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 hidden group-hover:block bg-zinc-900 text-white text-xs px-3 py-2 rounded-md max-w-[220px] w-max z-10 shadow-lg pointer-events-none">${escapeHtml(tooltip)}<div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-900"></div></div> | ||
| </div>`; | ||
|
Comment on lines
+213
to
219
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make severity tooltip reachable by keyboard users. At Line 214 and Line 218, the tooltip is hover-only on a non-focusable ♿ Suggested accessibility fix- return `<div class="flex items-center gap-2 relative group cursor-help" title="${escapeHtml(tooltip)}">
+ return `<div class="flex items-center gap-2 relative group cursor-help" title="${escapeHtml(tooltip)}" tabindex="0">
<span class="w-2.5 h-2.5 rounded-full ${dotClass}"></span>
<span class="text-lg font-bold tracking-tight">${count}</span>
<span class="text-sm text-muted-foreground">${label}</span>
- <div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 hidden group-hover:block bg-zinc-900 text-white text-xs px-3 py-2 rounded-md max-w-[220px] w-max z-10 shadow-lg pointer-events-none">${escapeHtml(tooltip)}<div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-900"></div></div>
+ <div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 bg-zinc-900 text-white text-xs px-3 py-2 rounded-md max-w-[220px] w-max z-10 shadow-lg pointer-events-none opacity-0 group-hover:opacity-100 group-focus:opacity-100 transition-opacity">${escapeHtml(tooltip)}<div class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-900"></div></div>
</div>`;🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.