From eb92929b876b87c946bd7709e387f71c40576b8c Mon Sep 17 00:00:00 2001 From: FindHao Date: Thu, 24 Jul 2025 16:22:15 -0400 Subject: [PATCH 1/3] Add ToggleSwitch component and integrate it into KernelOverview for sticky header functionality --- website/src/components/ToggleSwitch.tsx | 44 ++++++++++++++ website/src/pages/KernelOverview.tsx | 77 ++++++++++++++++++++++--- 2 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 website/src/components/ToggleSwitch.tsx diff --git a/website/src/components/ToggleSwitch.tsx b/website/src/components/ToggleSwitch.tsx new file mode 100644 index 0000000..67f0e7f --- /dev/null +++ b/website/src/components/ToggleSwitch.tsx @@ -0,0 +1,44 @@ +import React from "react"; + +interface ToggleSwitchProps { + isChecked: boolean; + onChange: (isChecked: boolean) => void; + label?: string; +} + +const ToggleSwitch: React.FC = ({ + isChecked, + onChange, + label, +}) => { + const handleToggle = () => { + onChange(!isChecked); + }; + + return ( +
+ {label && {label}} + +
+ ); +}; + +export default ToggleSwitch; \ No newline at end of file diff --git a/website/src/pages/KernelOverview.tsx b/website/src/pages/KernelOverview.tsx index b433e69..7903e24 100644 --- a/website/src/pages/KernelOverview.tsx +++ b/website/src/pages/KernelOverview.tsx @@ -1,7 +1,8 @@ -import React from "react"; +import React, { useState, useRef, useLayoutEffect, useCallback } from "react"; import ArgumentViewer from "../components/ArgumentViewer"; import DiffViewer from "../components/DiffViewer"; import { ProcessedKernel } from "../utils/dataLoader"; +import ToggleSwitch from "../components/ToggleSwitch"; interface KernelOverviewProps { kernels: ProcessedKernel[]; @@ -80,6 +81,33 @@ const KernelOverview: React.FC = ({ onSelectKernel, onViewIR, }) => { + const [isSticky, setIsSticky] = useState(true); + const [isCollapsed, setIsCollapsed] = useState(true); + const buttonsContainerRef = useRef(null); + + const adjustScroll = useCallback(() => { + if (isSticky && isCollapsed && buttonsContainerRef.current) { + const container = buttonsContainerRef.current; + const selectedButton = container.children[selectedKernel] as + | HTMLElement + | undefined; + + if (selectedButton) { + // Scroll the container to bring the selected button's row into view + container.scrollTop = selectedButton.offsetTop; + } + } + }, [isSticky, isCollapsed, selectedKernel]); + + useLayoutEffect(() => { + adjustScroll(); + + window.addEventListener("resize", adjustScroll); + return () => { + window.removeEventListener("resize", adjustScroll); + }; + }, [adjustScroll, kernels]); + if (kernels.length === 0) { return (
@@ -97,15 +125,50 @@ const KernelOverview: React.FC = ({ {/* Kernel Selection */} -
-

- Available Kernels -

-
+
isSticky && setIsCollapsed(false)} + onMouseLeave={() => isSticky && setIsCollapsed(true)} + > +
+

+ Available Kernels +

+
+ + Sticky Header + + +
+
+
{kernels.map((k, index) => (