Skip to content

Commit 57daa74

Browse files
authored
Merge pull request #36 from javaevolved/copilot/toggle-expand-collapse-cards
Add expand/collapse toggle for card code views
2 parents c4a4d41 + a36f164 commit 57daa74

File tree

3 files changed

+163
-2
lines changed

3 files changed

+163
-2
lines changed

site/app.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,19 @@
174174
card.classList.add('filter-hidden');
175175
}
176176
});
177+
178+
// Update view toggle button state
179+
if (window.updateViewToggleState) {
180+
window.updateViewToggleState();
181+
}
177182
});
178183
});
184+
185+
// Auto-click "All" button on page load to show all cards
186+
const allButton = document.querySelector('.filter-pill[data-filter="all"]');
187+
if (allButton) {
188+
allButton.click();
189+
}
179190
};
180191

181192
/* ==========================================================
@@ -211,6 +222,12 @@
211222
// Only handle touches on the card-code area
212223
if (!e.target.closest('.card-code')) return;
213224

225+
// Don't handle touch events when in expanded mode
226+
const tipsGrid = document.getElementById('tipsGrid');
227+
if (tipsGrid && tipsGrid.classList.contains('expanded')) {
228+
return;
229+
}
230+
214231
touchEndX = e.changedTouches[0].clientX;
215232
touchEndY = e.changedTouches[0].clientY;
216233

@@ -245,6 +262,11 @@
245262
// This is a safety net in case touch events trigger click as fallback
246263
card.addEventListener('click', (e) => {
247264
if (e.target.closest('.card-code')) {
265+
// Don't prevent navigation when in expanded mode
266+
const tipsGrid = document.getElementById('tipsGrid');
267+
if (tipsGrid && tipsGrid.classList.contains('expanded')) {
268+
return;
269+
}
248270
e.preventDefault();
249271
e.stopPropagation();
250272
}
@@ -470,6 +492,56 @@
470492
});
471493
};
472494

495+
/* ==========================================================
496+
6. View Toggle (Expand/Collapse All Cards)
497+
========================================================== */
498+
const initViewToggle = () => {
499+
const toggleBtn = document.getElementById('viewToggle');
500+
const tipsGrid = document.getElementById('tipsGrid');
501+
if (!toggleBtn || !tipsGrid) return;
502+
503+
let isExpanded = false;
504+
505+
const updateButtonState = () => {
506+
const visibleCards = document.querySelectorAll('.tip-card:not(.filter-hidden)');
507+
const hasVisibleCards = visibleCards.length > 0;
508+
509+
toggleBtn.disabled = !hasVisibleCards;
510+
if (!hasVisibleCards) {
511+
toggleBtn.style.opacity = '0.5';
512+
toggleBtn.style.cursor = 'not-allowed';
513+
} else {
514+
toggleBtn.style.opacity = '1';
515+
toggleBtn.style.cursor = 'pointer';
516+
}
517+
};
518+
519+
toggleBtn.addEventListener('click', () => {
520+
isExpanded = !isExpanded;
521+
522+
if (isExpanded) {
523+
tipsGrid.classList.add('expanded');
524+
toggleBtn.querySelector('.view-toggle-icon').textContent = '⊟';
525+
toggleBtn.querySelector('.view-toggle-text').textContent = 'Collapse All';
526+
527+
// Remove toggled class from all cards when expanding
528+
document.querySelectorAll('.tip-card').forEach(card => {
529+
card.classList.remove('toggled');
530+
});
531+
} else {
532+
tipsGrid.classList.remove('expanded');
533+
toggleBtn.querySelector('.view-toggle-icon').textContent = '⊞';
534+
toggleBtn.querySelector('.view-toggle-text').textContent = 'Expand All';
535+
}
536+
});
537+
538+
// Check initial state
539+
updateButtonState();
540+
541+
// Make updateButtonState available for filter to call
542+
window.updateViewToggleState = updateButtonState;
543+
};
544+
473545
/* ==========================================================
474546
Utilities
475547
========================================================== */
@@ -488,6 +560,7 @@
488560
});
489561
initFilters();
490562
initCardToggle();
563+
initViewToggle();
491564
initCopyButtons();
492565
initSyntaxHighlighting();
493566
initNewsletter();

site/styles.css

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ code, pre { font-family: 'JetBrains Mono', monospace; }
6363
--yellow: #fbbf24;
6464
--cyan: #22d3ee;
6565
--red-muted: #ef4444;
66-
--old-bg: #11100f;
67-
--modern-bg: #0f1117;
66+
--old-bg: #1a1412;
67+
--modern-bg: #0f1419;
6868
--radius: 16px;
6969
--radius-sm: 10px;
7070
--nav-bg: rgba(11, 11, 15, .8);
@@ -597,6 +597,88 @@ nav {
597597
gap: 8px;
598598
}
599599

600+
/* ---------- View Toggle Button ---------- */
601+
.view-toggle-wrap {
602+
display: flex;
603+
justify-content: center;
604+
margin: 16px 0;
605+
}
606+
607+
.view-toggle-btn {
608+
display: inline-flex;
609+
align-items: center;
610+
gap: 8px;
611+
padding: 10px 20px;
612+
font-size: 0.88rem;
613+
font-weight: 500;
614+
color: var(--text);
615+
background: var(--surface);
616+
border: 1px solid var(--border);
617+
border-radius: var(--radius-sm);
618+
cursor: pointer;
619+
transition: all 0.25s;
620+
}
621+
622+
.view-toggle-btn:hover {
623+
background: var(--surface-2);
624+
border-color: var(--border-light);
625+
transform: translateY(-2px);
626+
}
627+
628+
.view-toggle-icon {
629+
font-size: 1.1rem;
630+
line-height: 1;
631+
}
632+
633+
/* ---------- Expanded Mode ---------- */
634+
.tips-grid.expanded .tip-card {
635+
pointer-events: auto;
636+
}
637+
638+
.tips-grid.expanded .tip-card:hover {
639+
transform: none;
640+
box-shadow: none;
641+
}
642+
643+
.tips-grid.expanded .tip-card .card-code {
644+
display: flex;
645+
flex-direction: column;
646+
}
647+
648+
.tips-grid.expanded .tip-card .old-layer,
649+
.tips-grid.expanded .tip-card .modern-layer {
650+
position: static;
651+
opacity: 1;
652+
min-height: auto;
653+
border-top: 1px solid var(--border);
654+
}
655+
656+
.tips-grid.expanded .tip-card .old-layer {
657+
border-top: none;
658+
}
659+
660+
.tips-grid.expanded .tip-card .mini-label {
661+
position: relative;
662+
top: 0;
663+
right: 0;
664+
margin-bottom: 8px;
665+
}
666+
667+
.tips-grid.expanded .tip-card .hover-hint {
668+
display: none;
669+
}
670+
671+
/* Disable hover effects in expanded mode */
672+
.tips-grid.expanded .tip-card:hover .old-layer,
673+
.tips-grid.expanded .tip-card.toggled .old-layer {
674+
opacity: 1;
675+
}
676+
677+
.tips-grid.expanded .tip-card:hover .modern-layer,
678+
.tips-grid.expanded .tip-card.toggled .modern-layer {
679+
opacity: 1;
680+
}
681+
600682
/* ---------- Stats Bar ---------- */
601683
.stats-bar {
602684
display: flex;

templates/index.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,12 @@ <h2 class="section-title">All comparisons</h2>
240240
<button class="filter-pill" data-filter="security">Security</button>
241241
<button class="filter-pill" data-filter="tooling">Tooling</button>
242242
</div>
243+
<div class="view-toggle-wrap">
244+
<button class="view-toggle-btn" id="viewToggle" aria-label="Toggle view mode">
245+
<span class="view-toggle-icon"></span>
246+
<span class="view-toggle-text">Expand All</span>
247+
</button>
248+
</div>
243249
<div class="tips-grid" id="tipsGrid">
244250
{{tipCards}}
245251
</div>

0 commit comments

Comments
 (0)