feat: integrate scroll-to-top button in timeline

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Changed files
+16
src
components
+16
src/components/pages/grain-timeline.js
··· 8 8 import '../organisms/grain-comment-sheet.js'; 9 9 import '../molecules/grain-pull-to-refresh.js'; 10 10 import '../atoms/grain-spinner.js'; 11 + import '../atoms/grain-scroll-to-top.js'; 11 12 12 13 export class GrainTimeline extends LitElement { 13 14 static properties = { ··· 205 206 this._showScrollTop = window.scrollY > 150; 206 207 } 207 208 209 + async #handleScrollTop() { 210 + if (this._refreshing) return; 211 + 212 + window.scrollTo({ top: 0, behavior: 'smooth' }); 213 + 214 + // Wait for scroll to complete before refreshing 215 + await new Promise(resolve => setTimeout(resolve, 400)); 216 + 217 + await this.#handleRefresh(); 218 + } 219 + 208 220 render() { 209 221 return html` 210 222 <grain-feed-layout> ··· 238 250 @close=${this.#handleCommentSheetClose} 239 251 ></grain-comment-sheet> 240 252 </grain-feed-layout> 253 + <grain-scroll-to-top 254 + ?visible=${this._showScrollTop} 255 + @scroll-top=${this.#handleScrollTop} 256 + ></grain-scroll-to-top> 241 257 `; 242 258 } 243 259 }