a tool for shared writing and social publishing
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

added scrolling into view when cards are created or focused on

and it was a pain in the butt lol

celine a6d4f7c7 e36693a6

+68 -12
+64 -12
app/test/page.tsx
··· 8 8 export default function Index() { 9 9 let [cardRef, { width: cardWidth }] = useMeasure(); 10 10 let [cards, setCards] = useState([0]); 11 + let [focusedCardIndex, setFocusedCardIndex] = useState(0); 12 + let [focusedCard, { left: focusedCardPosition }] = useMeasure(); 11 13 12 14 return ( 13 15 <div className="pageWrapper h-screen flex flex-col gap-4 py-4"> 14 16 <PageHeader /> 15 17 16 - <div className="pageContentWrapper w-full overflow-x-scroll snap-mandatory snap-x grow items-stretch flex "> 17 - <div className="pageContent flex"> 18 + <div 19 + className="pageContentWrapper w-full relative overflow-x-scroll snap-x snap-mandatory grow items-stretch flex " 20 + id="card-carousel" 21 + > 22 + <div className="pageContent flex "> 18 23 <div 19 - className="bg-test" 24 + // className="bg-test" 20 25 style={{ width: `calc((100vw - ${cardWidth}px)/2)` }} 21 26 /> 22 27 23 28 {cards.map((card, index) => ( 24 29 <div 25 30 className="flex items-stretch" 26 - ref={index === 0 ? cardRef : null} 31 + ref={ 32 + index === 0 33 + ? cardRef 34 + : index === focusedCardIndex 35 + ? focusedCard 36 + : undefined 37 + } 27 38 > 28 - <Card first={index === 0} key={index} id={index.toString()}> 39 + <Card 40 + first={index === 0} 41 + focused={index === focusedCardIndex} 42 + id={index.toString()} 43 + key={index} 44 + > 29 45 Card {card} 30 46 <ButtonPrimary 31 47 onClick={() => { 32 48 //add a new card after this one 33 49 setCards([...cards, card + 1]); 50 + 51 + // focus the new card 52 + setFocusedCardIndex(index + 1); 34 53 35 54 //scroll the new card into view 36 - 37 55 setTimeout(() => { 38 56 let newCardID = document.getElementById( 39 57 (index + 1).toString(), 40 58 ); 41 59 newCardID?.scrollIntoView({ 42 60 behavior: "smooth", 43 - inline: "center", 61 + inline: "nearest", 44 62 }); 45 63 }, 100); 46 64 }} ··· 57 75 remove card 58 76 </ButtonPrimary> 59 77 )} 60 - {/* <ButtonPrimary onClick={() => {}}> 78 + <ButtonPrimary 79 + onClick={() => { 80 + //set the focused card to this one 81 + setFocusedCardIndex(index); 82 + 83 + // check if the card is off screen to the right or left 84 + let cardPosition = 85 + document 86 + .getElementById(index.toString()) 87 + ?.getBoundingClientRect().left || 0; 88 + let isOffScreenLeft = cardPosition < 0; 89 + let isOffScreenRight = 90 + cardPosition + cardWidth > window.innerWidth; 91 + 92 + //if card is off screen, scroll one card width to the left or right so that the card is in view 93 + setTimeout(() => { 94 + document.getElementById("card-carousel")?.scrollBy({ 95 + top: 0, 96 + left: isOffScreenLeft 97 + ? -cardWidth 98 + : isOffScreenRight 99 + ? cardWidth 100 + : 0, 101 + behavior: "smooth", 102 + }); 103 + }, 100); 104 + }} 105 + > 61 106 focus this card 62 - </ButtonPrimary> */} 107 + </ButtonPrimary> 63 108 </Card> 64 109 </div> 65 110 ))} 66 111 67 112 <div 68 - className="bg-test" 113 + // className="bg-test" 69 114 style={{ width: `calc((100vw / 2) - ${cardWidth}px + 12px )` }} 70 115 /> 71 116 </div> ··· 77 122 const Card = (props: { 78 123 children: React.ReactNode; 79 124 first?: boolean; 125 + focused?: boolean; 80 126 id: string; 81 127 }) => { 82 128 return ( 83 129 <> 84 130 {/* if the card is the first one in the list, remove this div... can we do with :before? */} 85 - {!props.first && <div className="w-6 snap-center" />} 131 + {!props.first && <div className="w-6 snap-center " />} 86 132 <div 87 133 id={props.id} 88 - className={`p-3 w-[calc(50vw-24px)] max-w-prose bg-bg-card border border-grey-80 rounded-lg grow flex flex-col gap-2 ${props.first && "snap-center"}`} 134 + className={` 135 + scroll-m-4 136 + p-3 w-[calc(50vw-24px)] max-w-[200px] 137 + bg-bg-card border border-grey-80 rounded-lg 138 + grow flex flex-col gap-2 139 + ${props.first && "snap-center"} 140 + ${props.focused && "border-4"}`} 89 141 > 90 142 {props.children} 91 143 </div>
+4
components/Icons.tsx
··· 1 + import { SVGProps } from "react"; 2 + 3 + type Props = SVGProps<SVGSVGElement>; 4 + 1 5 export const Home = (props: Props) => { 2 6 return ( 3 7 <svg