forked from pdsls.dev/pdsls
this repo has no description

collection filter background on scroll

futur.blue 789b172a cfc83a43

verified
Changed files
+38 -4
src
+38 -4
src/views/collection.tsx
··· 3 3 import { $type, ActorIdentifier, InferXRPCBodyOutput } from "@atcute/lexicons"; 4 4 import * as TID from "@atcute/tid"; 5 5 import { A, useParams } from "@solidjs/router"; 6 - import { createEffect, createResource, createSignal, For, Show, untrack } from "solid-js"; 6 + import { createEffect, createResource, createSignal, For, Show, untrack, onMount, onCleanup } from "solid-js"; 7 7 import { createStore } from "solid-js/store"; 8 8 import { Button } from "../components/button.jsx"; 9 9 import { JSONType, JSONValue } from "../components/json.jsx"; ··· 72 72 const [batchDelete, setBatchDelete] = createSignal(false); 73 73 const [lastSelected, setLastSelected] = createSignal<number>(); 74 74 const [reverse, setReverse] = createSignal(false); 75 + const [filterStuck, setFilterStuck] = createSignal(false); 75 76 const did = params.repo; 76 77 let pds: string; 77 78 let rpc: Client; 79 + let sticky!: HTMLDivElement; 78 80 79 81 const fetchRecords = async () => { 80 82 if (!pds) pds = await resolvePDS(did); ··· 157 159 true, 158 160 ); 159 161 162 + onMount(() => { 163 + let ticking = false; 164 + const tick = () => { 165 + const topPx = parseFloat(getComputedStyle(sticky).top); 166 + const { top } = sticky.getBoundingClientRect(); 167 + setFilterStuck(top <= topPx + 0.5); 168 + ticking = false; 169 + }; 170 + 171 + const onScroll = () => { 172 + if (!ticking) { 173 + ticking = true; 174 + requestAnimationFrame(tick); 175 + } 176 + }; 177 + 178 + window.addEventListener("scroll", onScroll, { passive: true }); 179 + 180 + tick(); 181 + 182 + onCleanup(() => { 183 + window.removeEventListener("scroll", onScroll); 184 + }); 185 + }); 186 + 160 187 return ( 161 188 <Show when={records.length || response()}> 162 189 <div class="flex w-full flex-col items-center"> 163 - <div class="dark:bg-dark-500 sticky top-0 z-5 flex w-screen flex-col items-center justify-center gap-2 bg-neutral-100 pt-1 pb-3"> 164 - <div class="flex w-[22rem] items-center gap-2 sm:w-[24rem]"> 190 + <div 191 + ref={(el) => (sticky = el)} 192 + class="sticky top-2 z-10 flex flex-col items-center justify-center gap-2 rounded-lg p-3 transition-colors" 193 + classList={{ 194 + "bg-neutral-50 dark:bg-dark-300 border-[0.5px] border-neutral-300 dark:border-neutral-700 shadow-md": filterStuck(), 195 + "bg-transparent border-transparent shadow-none": !filterStuck(), 196 + }} 197 + > 198 + <div class="z-20 flex w-[22rem] items-center gap-2 sm:w-[24rem]"> 165 199 <Show when={agent() && agent()?.sub === did}> 166 200 <div class="flex items-center gap-x-2"> 167 201 <Tooltip ··· 220 254 /> 221 255 </div> 222 256 <Show when={records.length > 1}> 223 - <div class="flex w-[22rem] items-center justify-between gap-x-2 sm:w-[24rem]"> 257 + <div class="z-20 flex w-[22rem] items-center justify-between gap-x-2 sm:w-[24rem]"> 224 258 <Button 225 259 onClick={() => { 226 260 setReverse(!reverse());