diff --git a/src/DotNetApiDiff/Reporting/HtmlTemplates/main-layout.scriban b/src/DotNetApiDiff/Reporting/HtmlTemplates/main-layout.scriban index fdbd2b1..b70a2e5 100644 --- a/src/DotNetApiDiff/Reporting/HtmlTemplates/main-layout.scriban +++ b/src/DotNetApiDiff/Reporting/HtmlTemplates/main-layout.scriban @@ -56,22 +56,50 @@ 📈 Summary + {{if result.summary.added_count > 0}} + + {{ result.summary.added_count }} + Added + + {{else}} {{ result.summary.added_count }} Added + {{end}} + {{if result.summary.removed_count > 0}} + + {{ result.summary.removed_count }} + Removed + + {{else}} {{ result.summary.removed_count }} Removed + {{end}} + {{if result.summary.modified_count > 0}} + + {{ result.summary.modified_count }} + Modified + + {{else}} {{ result.summary.modified_count }} Modified + {{end}} + {{if result.summary.breaking_changes_count > 0}} + + {{ result.summary.breaking_changes_count }} + Breaking + + {{else}} {{ result.summary.breaking_changes_count }} Breaking + {{end}} @@ -91,13 +119,19 @@ {{if result.has_breaking_changes}} - - ⚠️ Breaking Changes - - Warning: The following changes may break compatibility with existing code. + + + ⚠️ Breaking Changes + + ▶ + - - + + + Warning: The following changes may break compatibility with existing code. + + + @@ -119,17 +153,25 @@ + {{end}} {{for section in change_sections}} - - {{ section.icon }} {{ section.title }} ({{ section.count }}) - {{if section.description}} - {{ section.description }} - {{end}} - {{ render_change_group section }} + + + {{ section.icon }} {{ section.title }} ({{ section.count }}) + + ▶ + + + + {{if section.description}} + {{ section.description }} + {{end}} + {{ render_change_group section }} + {{end}} diff --git a/src/DotNetApiDiff/Reporting/HtmlTemplates/scripts.js b/src/DotNetApiDiff/Reporting/HtmlTemplates/scripts.js index a24cc91..e21bf9f 100644 --- a/src/DotNetApiDiff/Reporting/HtmlTemplates/scripts.js +++ b/src/DotNetApiDiff/Reporting/HtmlTemplates/scripts.js @@ -30,3 +30,104 @@ function toggleConfig() { text.textContent = 'Show Configuration Details'; } } + +// Session storage helpers +function setSectionState(sectionId, state) { + try { + sessionStorage.setItem('section-' + sectionId, state); + } catch (e) { + // Ignore storage errors + } +} + +function getSectionState(sectionId) { + try { + return sessionStorage.getItem('section-' + sectionId); + } catch (e) { + return null; + } +} + +// New collapsible section functionality +function toggleSection(sectionId) { + const section = document.getElementById(sectionId); + const content = document.getElementById(sectionId + '-content'); + const button = section.querySelector('.section-toggle'); + const icon = button.querySelector('.toggle-icon'); + + if (content.classList.contains('collapsed')) { + // Expand section + content.classList.remove('collapsed'); + button.classList.remove('collapsed'); + icon.textContent = '▶'; // Keep using ▶ and let CSS handle rotation + setSectionState(sectionId, 'expanded'); + } else { + // Collapse section + content.classList.add('collapsed'); + button.classList.add('collapsed'); + icon.textContent = '▶'; // Keep using ▶ and let CSS handle rotation + setSectionState(sectionId, 'collapsed'); + } +} + +// Navigate to section with smooth scrolling and auto-expand +function navigateToSection(sectionId) { + const section = document.getElementById(sectionId); + const content = document.getElementById(sectionId + '-content'); + + if (!section) return; + + // Auto-expand if collapsed + if (content && content.classList.contains('collapsed')) { + toggleSection(sectionId); + } + + // Smooth scroll to section + section.scrollIntoView({ + behavior: 'smooth', + block: 'start' + }); + + // Brief highlight effect + section.style.transition = 'box-shadow 0.3s ease'; + section.style.boxShadow = '0 0 20px rgba(0, 123, 255, 0.3)'; + setTimeout(() => { + section.style.boxShadow = ''; + }, 1500); +} + +// Initialize sections to collapsed state by default +function initializeSections() { + const sections = ['breaking-changes', 'added-items', 'removed-items', 'modified-items']; + + sections.forEach(sectionId => { + const section = document.getElementById(sectionId); + const content = document.getElementById(sectionId + '-content'); + const button = section?.querySelector('.section-toggle'); + const icon = button?.querySelector('.toggle-icon'); + + if (!section || !content || !button || !icon) return; + + // Check session storage first + const savedState = getSectionState(sectionId); + + if (savedState === 'expanded') { + // Expand based on saved state + content.classList.remove('collapsed'); + button.classList.remove('collapsed'); + icon.textContent = '▶'; + } else { + // Default to collapsed (including null/new sessions) + content.classList.add('collapsed'); + button.classList.add('collapsed'); + icon.textContent = '▶'; + // Save the default state if not already set + if (savedState === null) { + setSectionState(sectionId, 'collapsed'); + } + } + }); +} + +// Initialize sections when the page loads +document.addEventListener('DOMContentLoaded', initializeSections); diff --git a/src/DotNetApiDiff/Reporting/HtmlTemplates/styles.css b/src/DotNetApiDiff/Reporting/HtmlTemplates/styles.css index bd8bfb1..d31d381 100644 --- a/src/DotNetApiDiff/Reporting/HtmlTemplates/styles.css +++ b/src/DotNetApiDiff/Reporting/HtmlTemplates/styles.css @@ -54,6 +54,84 @@ section h2 { font-size: 1.5rem; } +/* Collapsible Section Styles */ +.section-header { + display: flex; + justify-content: space-between; + align-items: center; + background: #f8f9fa; + padding: 15px 20px; + margin: 0; + border-bottom: 1px solid #dee2e6; +} + +.section-header h2 { + background: none; + padding: 0; + margin: 0; + border: none; + font-size: 1.5rem; +} + +.section-toggle { + background: none; + border: none; + cursor: pointer; + padding: 8px; + border-radius: 4px; + color: #6c757d; + transition: all 0.2s ease; + display: flex; + align-items: center; + justify-content: center; + min-width: 32px; + min-height: 32px; +} + +.section-toggle:hover { + background-color: #e9ecef; + color: #495057; +} + +.section-toggle:focus { + outline: 2px solid #007bff; + outline-offset: 2px; +} + +.toggle-icon { + font-size: 14px; + transition: transform 0.3s ease; +} + +.section-toggle.collapsed .toggle-icon { + transform: rotate(0deg); /* No rotation - ▶ points right when collapsed */ +} + +.section-toggle:not(.collapsed) .toggle-icon { + transform: rotate(90deg); /* Rotate ▶ to point down when expanded */ +} + +.section-content { + transition: all 0.3s ease; + overflow: hidden; +} + +.section-content.collapsed { + max-height: 0; + opacity: 0; + padding-top: 0; + padding-bottom: 0; + margin-top: 0; + margin-bottom: 0; +} + +.section-content:not(.collapsed) { + max-height: none; + opacity: 1; + padding-top: 0; + padding-bottom: 0; +} + .metadata-content { padding: 20px; } @@ -157,6 +235,21 @@ section h2 { border-radius: 8px; color: white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.summary-card.clickable { + cursor: pointer; +} + +.summary-card.clickable:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); +} + +.summary-card.clickable:active { + transform: translateY(0); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .summary-card.added {
{{ section.description }}