feat: Toolbar redesign#202
Open
dermatz wants to merge 49 commits into
Open
Conversation
…hts, and menu components
…er structure and maintainability
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Comment on lines
+53
to
+67
| if (hasErrors) { | ||
| applyHighlight(errors, key, context, { | ||
| severity: "error", | ||
| autoFindings: true, | ||
| formatFinding: () => ({ action: "Show affected element" }), | ||
| }); | ||
| } | ||
| if (hasWarnings) { | ||
| applyHighlight(warnings, key, context, { | ||
| severity: "warning", | ||
| autoFindings: true, | ||
| formatFinding: () => ({ action: "Show affected element" }), | ||
| }); | ||
| } | ||
|
|
Comment on lines
+23
to
+31
| this.activeAudits.delete(auditKey); | ||
| audit.run(this, false); | ||
| try { | ||
| audit.run(this, false); | ||
| } catch (err) { | ||
| console.warn( | ||
| `[MageForge] Audit "${auditKey}" failed on deactivate:`, | ||
| err, | ||
| ); | ||
| } |
| const list = document.createElement("div"); | ||
| list.className = "mageforge-findings-list"; | ||
|
|
||
| findings.forEach(({ el, selector, severity = "error" }, index) => { |
Comment on lines
+1048
to
+1051
| const actionEl = document.createElement("span"); | ||
| actionEl.className = "mageforge-finding-action"; | ||
| actionEl.textContent = "Show Element"; | ||
|
|
Comment on lines
+1433
to
+1438
| _getFocusableEls() { | ||
| return Array.from( | ||
| this.menu.querySelectorAll( | ||
| 'button:not([disabled]), [href], input:not([disabled]), [tabindex]:not([tabindex="-1"])', | ||
| ), | ||
| ).filter((el) => !el.closest("[hidden]")); |
Comment on lines
+15
to
+25
| .mageforge-toolbar[data-theme="light"] .mageforge-toolbar-menu { | ||
| --mageforge-bg-dark: rgba(255, 255, 255, 0.98); | ||
| --mageforge-bg-dark-alt: rgba(248, 250, 252, 0.98); | ||
| --mageforge-border-color: rgba(0, 0, 0, 0.12); | ||
| --mageforge-surface-glass-hover: rgba(0, 0, 0, 0.05); | ||
| --mageforge-shadow-sm: rgba(0, 0, 0, 0.1); | ||
| --mageforge-shadow-md: rgba(0, 0, 0, 0.15); | ||
| --mageforge-shadow-lg: rgba(0, 0, 0, 0.2); | ||
| --mageforge-color-white: #0f172a; | ||
| --mageforge-color-slate-400: #64748b; | ||
| } |
Comment on lines
+36
to
+52
| @media (prefers-color-scheme: light) { | ||
| .mageforge-toolbar[data-theme="auto"] .mageforge-toolbar-menu { | ||
| --mageforge-bg-dark: rgba(255, 255, 255, 0.98); | ||
| --mageforge-bg-dark-alt: rgba(248, 250, 252, 0.98); | ||
| --mageforge-border-color: rgba(0, 0, 0, 0.12); | ||
| --mageforge-surface-glass-hover: rgba(0, 0, 0, 0.05); | ||
| --mageforge-shadow-sm: rgba(0, 0, 0, 0.1); | ||
| --mageforge-shadow-md: rgba(0, 0, 0, 0.15); | ||
| --mageforge-shadow-lg: rgba(0, 0, 0, 0.2); | ||
| --mageforge-color-white: #0f172a; | ||
| --mageforge-color-slate-400: #64748b; | ||
| } | ||
|
|
||
| .mageforge-toolbar[data-theme="auto"] .mageforge-toolbar-menu-toggle { | ||
| background: var(--mageforge-toggle-bg-off-light); | ||
| } | ||
| } |
Comment on lines
+463
to
+471
| _buildPanelHeader(title, showScore, groupKey) { | ||
| const header = document.createElement("div"); | ||
| header.setAttribute("role", "button"); | ||
| header.setAttribute("tabindex", "0"); | ||
| header.className = "mageforge-toolbar-menu-group-header"; | ||
| header.setAttribute( | ||
| "aria-expanded", | ||
| String(!this.collapsedGroups.has(key)), | ||
| ); | ||
| header.onclick = (e) => { | ||
| e.preventDefault(); | ||
| header.className = "mageforge-tab-panel-header"; | ||
| header.dataset.group = groupKey; | ||
|
|
||
| const titleEl = document.createElement("h2"); | ||
| titleEl.className = "mageforge-tab-panel-title"; | ||
| titleEl.textContent = title; | ||
| header.appendChild(titleEl); |
Comment on lines
+188
to
+198
| _buildTabNav() { | ||
| const nav = document.createElement("nav"); | ||
| nav.className = "mageforge-toolbar-tab-nav"; | ||
| nav.setAttribute("role", "tablist"); | ||
| nav.setAttribute("aria-label", "Audit categories"); | ||
|
|
||
| // Action bar (run/reset for the current tab). | ||
| // column-reverse means the first DOM child appears at the visual bottom. | ||
| this.footerActionBar = document.createElement("div"); | ||
| this.footerActionBar.className = "mageforge-nav-action-bar"; | ||
| nav.appendChild(this.footerActionBar); |
Comment on lines
+1029
to
+1031
| const row = document.createElement("div"); | ||
| row.className = `mageforge-audit-finding mageforge-audit-finding--${severity}`; | ||
|
|
Comment on lines
+1050
to
+1055
| row.addEventListener("click", (e) => { | ||
| e.stopPropagation(); | ||
| el.scrollIntoView({ behavior: "smooth", block: "center" }); | ||
| el.classList.add("mageforge-finding-flash"); | ||
| setTimeout(() => el.classList.remove("mageforge-finding-flash"), 1200); | ||
| }); |
| * @returns {HTMLDivElement} | ||
| */ | ||
| _buildScoreWidget() { | ||
| const gradId = `mf-sg-${crypto.randomUUID().slice(0, 8)}`; |
| const panel = document.createElement("div"); | ||
| panel.className = "mageforge-home-panel"; | ||
|
|
||
| const gradId = `mf-gauge-${crypto.randomUUID().slice(0, 8)}`; |
Comment on lines
+154
to
+160
| // Deactivate existing audits in this group | ||
| groupAudits.forEach((audit) => { | ||
| if (this.activeAudits.has(audit.key)) { | ||
| this.activeAudits.delete(audit.key); | ||
| audit.run(this, false); | ||
| } | ||
| }); |
Comment on lines
+11
to
+26
| @import url("toolbar/_variables.css"); | ||
| @import url("toolbar/_reset.css"); | ||
| @import url("toolbar/_burger.css"); | ||
| @import url("toolbar/_menu.css"); | ||
| @import url("toolbar/_groups.css"); | ||
| @import url("toolbar/_findings.css"); | ||
| @import url("toolbar/_highlights.css"); | ||
| @import url("toolbar/_feedback.css"); | ||
| @import url("toolbar/_animations.css"); | ||
| @import url("toolbar/_footer.css"); | ||
| @import url("toolbar/_health.css"); | ||
| @import url("toolbar/_buttons.css"); | ||
| @import url("toolbar/_credit.css"); | ||
| @import url("toolbar/_positions.css"); | ||
| @import url("toolbar/_themes.css"); | ||
| @import url("toolbar/_responsive.css"); |
Comment on lines
+126
to
+147
| /** | ||
| * Build a short, human-readable CSS selector for labelling a finding. | ||
| * | ||
| * @param {Element} el | ||
| * @returns {string} | ||
| */ | ||
| export function getReadableSelector(el) { | ||
| if (el.id) return `#${el.id}`; | ||
| const tag = el.tagName.toLowerCase(); | ||
| const classes = [...el.classList] | ||
| .filter((c) => !c.startsWith("mageforge")) | ||
| .slice(0, 2) | ||
| .join("."); | ||
| if (classes) return `${tag}.${classes}`; | ||
| const ariaLabel = el.getAttribute("aria-label"); | ||
| if (ariaLabel) return `${tag}[aria-label]`; | ||
| if (el.name) return `${tag}[name="${el.name}"]`; | ||
| if (tag === "img" && el.src) { | ||
| const base = el.src.split("/").pop().split("?")[0].slice(0, 24); | ||
| return `img/${base}`; | ||
| } | ||
| return tag; |
Comment on lines
+469
to
+473
| titleEl.className = "mageforge-tab-panel-title"; | ||
| titleEl.textContent = title; | ||
| header.appendChild(titleEl); | ||
|
|
||
| return header; |
| * @returns {HTMLDivElement} | ||
| */ | ||
| _buildScoreWidget() { | ||
| const gradId = `mf-sg-${crypto.randomUUID().slice(0, 8)}`; |
| const panel = document.createElement("div"); | ||
| panel.className = "mageforge-home-panel"; | ||
|
|
||
| const gradId = `mf-gauge-${crypto.randomUUID().slice(0, 8)}`; |
Comment on lines
+28
to
+32
| .mageforge-toolbar-tab-nav { | ||
| display: flex; | ||
| flex-direction: column-reverse; | ||
| width: 200px; | ||
| flex-shrink: 0; |
Comment on lines
+29
to
+44
| /* Sidebar: leicht abgesetzt vom weißen Content-Bereich */ | ||
| .mageforge-toolbar[data-theme="light"] .mageforge-toolbar-tab-nav { | ||
| background: #f8fafc; | ||
| } | ||
|
|
||
| /* Home-Tab active: weißer Alpha-Wert unsichtbar auf hellem Hintergrund */ | ||
| .mageforge-toolbar[data-theme="light"] | ||
| .mageforge-toolbar-tab-btn[data-tab="home"].mageforge-tab-active { | ||
| background: rgba(0, 0, 0, 0.07); | ||
| } | ||
|
|
||
| /* Gruppen-Tab active: Alpha leicht erhöhen für bessere Sichtbarkeit */ | ||
| .mageforge-toolbar[data-theme="light"] | ||
| .mageforge-toolbar-tab-btn[data-tab="wcag"].mageforge-tab-active { | ||
| background: rgba(168, 85, 247, 0.14); | ||
| } |
Comment on lines
+61
to
+75
| /* Theme-Toggle-Pill: hardcodiertes weißes Alpha durch dunkles ersetzen */ | ||
| .mageforge-toolbar[data-theme="light"] .mageforge-theme-toggle { | ||
| background: rgba(0, 0, 0, 0.06); | ||
| } | ||
|
|
||
| .mageforge-toolbar[data-theme="light"] .mageforge-theme-btn:hover { | ||
| background: rgba(0, 0, 0, 0.08); | ||
| } | ||
|
|
||
| /* Gradient-Buttons: Textfarbe explizit weiß halten (nicht #0f172a erben) */ | ||
| .mageforge-toolbar[data-theme="light"] .mageforge-toolbar-menu-run-all, | ||
| .mageforge-toolbar[data-theme="light"] .mageforge-home-check-btn, | ||
| .mageforge-toolbar[data-theme="light"] .mageforge-group-run-btn { | ||
| color: #ffffff; | ||
| } |
Comment on lines
+24
to
+39
| () => { | ||
| return Array.from( | ||
| document.querySelectorAll('button svg, a svg, [role="button"] svg'), | ||
| ).filter((svg) => { | ||
| // Skip toolbar's own SVGs | ||
| if (svg.closest(".mageforge-toolbar")) return false; | ||
| // Already hidden from AT | ||
| if (svg.getAttribute("aria-hidden") === "true") return false; | ||
| // Has a <title> → informative, not decorative | ||
| if (svg.querySelector("title")) return false; | ||
| // Has aria-label or aria-labelledby → informative | ||
| if (svg.getAttribute("aria-label") || svg.getAttribute("aria-labelledby")) | ||
| return false; | ||
| return true; | ||
| }); | ||
| }, |
Comment on lines
+11
to
+26
| @import url("toolbar/_variables.css"); | ||
| @import url("toolbar/_reset.css"); | ||
| @import url("toolbar/_burger.css"); | ||
| @import url("toolbar/_menu.css"); | ||
| @import url("toolbar/_groups.css"); | ||
| @import url("toolbar/_findings.css"); | ||
| @import url("toolbar/_highlights.css"); | ||
| @import url("toolbar/_feedback.css"); | ||
| @import url("toolbar/_animations.css"); | ||
| @import url("toolbar/_footer.css"); | ||
| @import url("toolbar/_health.css"); | ||
| @import url("toolbar/_buttons.css"); | ||
| @import url("toolbar/_credit.css"); | ||
| @import url("toolbar/_positions.css"); | ||
| @import url("toolbar/_themes.css"); | ||
| @import url("toolbar/_responsive.css"); |
Comment on lines
+154
to
+160
| // Deactivate existing audits in this group | ||
| groupAudits.forEach((audit) => { | ||
| if (this.activeAudits.has(audit.key)) { | ||
| this.activeAudits.delete(audit.key); | ||
| audit.run(this, false); | ||
| } | ||
| }); |
…r score widget ID usage
Comment on lines
+65
to
+70
| function generateId(prefix) { | ||
| const rand = | ||
| crypto.randomUUID?.().slice(0, 8) ?? | ||
| Math.random().toString(36).slice(2, 10); | ||
| return `mf-${prefix}-${rand}`; | ||
| } |
| <div>${createLogoSvg("#E5622A")}</div> | ||
| <span class="mageforge-toolbar-menu-title-text">MageForge</span> | ||
| </div> | ||
| <button type="button" class="mageforge-toolbar-menu-close" title="Close & deactivate all"> |
Comment on lines
+1031
to
+1032
| const row = document.createElement("div"); | ||
| row.className = `mageforge-audit-finding mageforge-audit-finding--${severity}`; |
Comment on lines
+38
to
+44
| } catch (err) { | ||
| console.warn( | ||
| `[MageForge] Audit "${auditKey}" failed on activate:`, | ||
| err, | ||
| ); | ||
| this.activeAudits.delete(auditKey); | ||
| } |
Comment on lines
+154
to
+160
| // Deactivate existing audits in this group | ||
| groupAudits.forEach((audit) => { | ||
| if (this.activeAudits.has(audit.key)) { | ||
| this.activeAudits.delete(audit.key); | ||
| audit.run(this, false); | ||
| } | ||
| }); |
Comment on lines
+27
to
+30
| const type = (s.getAttribute("type") || "").toLowerCase(); | ||
| // Module scripts are deferred by spec; non-JS types are not executed | ||
| if (type && type !== "text/javascript") return false; | ||
| return !s.hasAttribute("defer") && !s.hasAttribute("async"); |
…nagement, and score animations
Comment on lines
+27
to
+30
| const type = (s.getAttribute("type") || "").toLowerCase(); | ||
| // Module scripts are deferred by spec; non-JS types are not executed | ||
| if (type && type !== "text/javascript") return false; | ||
| return !s.hasAttribute("defer") && !s.hasAttribute("async"); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request removes the "Show Health Score" feature toggle from the MageForge Inspector toolbar, including its configuration, translations, and UI integration. Additionally, it introduces several new modular CSS files to enhance and organize the toolbar's frontend styles, covering animations, buttons, burger menu, feedback toasts, and credit links.
Removal of "Show Health Score" Feature Toggle:
show_health_scoreconfiguration option from all relevant files, includingconfig.xml,system.xml, and theInspectorConfigclass. This also removes the associated getter method from the block and the related data attribute from the toolbar template. [1] [2] [3] [4] [5]Frontend Style Improvements:
_animations.css) for keyframe effects._burger.css) for the main toolbar toggle._buttons.css) for toolbar actions, including run, reset, and feature request buttons._feedback.css) for success and error messages._credit.css) for the footer credit section.