feat(ui): add scroll-to-bottom button on issues page
Shows a floating arrow button in the bottom-right corner when the user is more than 300px from the bottom of the issues list. Hides automatically when near the bottom. Smooth-scrolls on click. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,7 +17,7 @@ import { Input } from "@/components/ui/input";
|
|||||||
import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover";
|
import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@/components/ui/collapsible";
|
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@/components/ui/collapsible";
|
||||||
import { CircleDot, Plus, Filter, ArrowUpDown, Layers, Check, X, ChevronRight, List, Columns3, User, Search } from "lucide-react";
|
import { CircleDot, Plus, Filter, ArrowUpDown, Layers, Check, X, ChevronRight, List, Columns3, User, Search, ArrowDown } from "lucide-react";
|
||||||
import { KanbanBoard } from "./KanbanBoard";
|
import { KanbanBoard } from "./KanbanBoard";
|
||||||
import type { Issue } from "@paperclipai/shared";
|
import type { Issue } from "@paperclipai/shared";
|
||||||
|
|
||||||
@@ -218,6 +218,24 @@ export function IssuesList({
|
|||||||
|
|
||||||
const activeFilterCount = countActiveFilters(viewState);
|
const activeFilterCount = countActiveFilters(viewState);
|
||||||
|
|
||||||
|
const [showScrollBottom, setShowScrollBottom] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
const el = document.getElementById("main-content");
|
||||||
|
if (!el) return;
|
||||||
|
const check = () => {
|
||||||
|
const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
|
||||||
|
setShowScrollBottom(distanceFromBottom > 300);
|
||||||
|
};
|
||||||
|
check();
|
||||||
|
el.addEventListener("scroll", check, { passive: true });
|
||||||
|
return () => el.removeEventListener("scroll", check);
|
||||||
|
}, [filtered.length]);
|
||||||
|
|
||||||
|
const scrollToBottom = useCallback(() => {
|
||||||
|
const el = document.getElementById("main-content");
|
||||||
|
if (el) el.scrollTo({ top: el.scrollHeight, behavior: "smooth" });
|
||||||
|
}, []);
|
||||||
|
|
||||||
const groupedContent = useMemo(() => {
|
const groupedContent = useMemo(() => {
|
||||||
if (viewState.groupBy === "none") {
|
if (viewState.groupBy === "none") {
|
||||||
return [{ key: "__all", label: null as string | null, items: filtered }];
|
return [{ key: "__all", label: null as string | null, items: filtered }];
|
||||||
@@ -706,6 +724,15 @@ export function IssuesList({
|
|||||||
</Collapsible>
|
</Collapsible>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
{showScrollBottom && (
|
||||||
|
<button
|
||||||
|
onClick={scrollToBottom}
|
||||||
|
className="fixed bottom-6 right-6 z-40 flex h-9 w-9 items-center justify-center rounded-full border border-border bg-background shadow-md hover:bg-accent transition-colors"
|
||||||
|
aria-label="Scroll to bottom"
|
||||||
|
>
|
||||||
|
<ArrowDown className="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user