an app to share curated trails sidetrail.app
atproto nextjs react rsc

super evil hack to keep ranking working with masonry

+26 -18
+7 -1
app/HomeTrailsList.css
··· 14 14 15 15 @media (max-width: 768px) { 16 16 .HomeTrailsList-grid { 17 - column-count: 1; 17 + column-count: unset; 18 + display: flex; 19 + flex-direction: column; 20 + } 21 + 22 + .HomeTrailsList-grid > * { 23 + order: var(--original-index); 18 24 } 19 25 }
+19 -17
app/HomeTrailsList.tsx
··· 12 12 // We put odd-ranked items first (left col), then even-ranked (right col). 13 13 // Visual order reads left-to-right: 1,2 / 3,4 / 5,6 14 14 // Tab order follows DOM: 1 -> 3 -> 5 -> 2 -> 4 -> 6 (column-wise) 15 - function interleaveForMasonry<T>(items: T[]): T[] { 16 - const result: T[] = []; 15 + // On mobile, CSS order property restores original ranking. 16 + function interleaveForMasonry<T>(items: T[]): { item: T; originalIndex: number }[] { 17 + const result: { item: T; originalIndex: number }[] = []; 17 18 for (let i = 0; i < items.length; i += 2) { 18 - result.push(items[i]); 19 + result.push({ item: items[i], originalIndex: i }); 19 20 } 20 21 for (let i = 1; i < items.length; i += 2) { 21 - result.push(items[i]); 22 + result.push({ item: items[i], originalIndex: i }); 22 23 } 23 24 return result; 24 25 } ··· 34 35 35 36 return ( 36 37 <div className="HomeTrailsList-grid"> 37 - {reordered.map((trail) => ( 38 - <TrailCard 39 - key={trail.uri} 40 - uri={trail.uri} 41 - rkey={trail.rkey} 42 - creatorHandle={trail.creatorHandle} 43 - title={trail.title} 44 - description={trail.description} 45 - accentColor={trail.accentColor} 46 - backgroundColor={trail.backgroundColor} 47 - creator={trail.creator} 48 - stopsCount={trail.stopsCount} 49 - /> 38 + {reordered.map(({ item: trail, originalIndex }) => ( 39 + <div key={trail.uri} style={{ "--original-index": originalIndex } as React.CSSProperties}> 40 + <TrailCard 41 + uri={trail.uri} 42 + rkey={trail.rkey} 43 + creatorHandle={trail.creatorHandle} 44 + title={trail.title} 45 + description={trail.description} 46 + accentColor={trail.accentColor} 47 + backgroundColor={trail.backgroundColor} 48 + creator={trail.creator} 49 + stopsCount={trail.stopsCount} 50 + /> 51 + </div> 50 52 ))} 51 53 </div> 52 54 );