gabriel / musehub public
mist-list.ts typescript
44 lines 1.7 KB
Raw
sha256:3ff9c9863a9891bdcde71b4a43228f66d0493e38b7cc1d09fe9eb7de774046b2 feat: add repair-commit wire endpoint (API parity with repa… Opus 4.8 minor ⚠ breaking 1 day ago
1 /**
2 * mist-list.ts — Mist list and explore page module.
3 *
4 * Responsibilities:
5 * 1. Row hover entrance animations (staggered IntersectionObserver).
6 * 2. Re-animate rows after HTMX fragment swap (type-filter navigation).
7 */
8
9 // ── Row entrance animations ───────────────────────────────────────────────────
10
11 function animateRows(root: Element | Document = document): void {
12 const rows = root.querySelectorAll<HTMLElement>('.ms-row');
13 if (!rows.length) return;
14
15 const io = new IntersectionObserver((entries) => {
16 entries.forEach((entry, i) => {
17 if (!entry.isIntersecting) return;
18 const el = entry.target as HTMLElement;
19 el.style.animationDelay = `${i * 20}ms`;
20 io.unobserve(el);
21 });
22 }, { threshold: 0.02 });
23
24 rows.forEach(el => io.observe(el));
25 }
26
27 // ── HTMX: re-animate after fragment swap ─────────────────────────────────────
28
29 function bindHtmxSwap(): void {
30 document.body.addEventListener('htmx:afterSwap', (e: Event) => {
31 const target = (e as CustomEvent).detail?.target as HTMLElement | undefined;
32 if (!target) return;
33 if (target.id === 'mist-rows' || target.closest('#mist-rows')) {
34 animateRows(target);
35 }
36 });
37 }
38
39 // ── Entry point ───────────────────────────────────────────────────────────────
40
41 export function initMistList(_data?: Record<string, unknown>): void {
42 animateRows();
43 bindHtmxSwap();
44 }
File History 1 commit
sha256:3ff9c9863a9891bdcde71b4a43228f66d0493e38b7cc1d09fe9eb7de774046b2 feat: add repair-commit wire endpoint (API parity with repa… Opus 4.8 minor 1 day ago