MCPcopy Create free account
hub / github.com/DavidHDev/react-bits / Sidebar

Function Sidebar

src/components/navs/Sidebar.jsx:346–561  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

344
345// ─── Main Component ──────────────────────────────────────────────────────────
346const Sidebar = () => {
347 // State
348 const [isDrawerOpen, setDrawerOpen] = useState(false);
349 const [isSponsorsOpen, setSponsorsOpen] = useState(false);
350 const [linePosition, setLinePosition] = useState(null);
351 const [isLineVisible, setIsLineVisible] = useState(false);
352 const [hoverLinePosition, setHoverLinePosition] = useState(null);
353 const [isHoverLineVisible, setIsHoverLineVisible] = useState(false);
354 const [pendingActivePath, setPendingActivePath] = useState(null);
355
356 // Refs
357 const sidebarRef = useRef(null);
358 const sidebarContainerRef = useRef(null);
359 const itemRefs = useRef({});
360 const hoverTimeoutRef = useRef(null);
361 const hoverDelayTimeoutRef = useRef(null);
362
363 // Hooks
364 const location = useLocation();
365 const navigate = useNavigate();
366 const { toggleSearch } = useSearch();
367 const { startTransition, isTransitioning } = useTransition();
368 const savedSet = useFavoritesSync();
369 const isScrolledToBottom = useScrolledToBottom(sidebarContainerRef);
370
371 // Helpers
372 const findActiveElement = useCallback(() => {
373 const activePath = pendingActivePath || location.pathname;
374 for (const category of CATEGORIES) {
375 const activeItem = category.subcategories.find(sub => activePath === `/${slug(category.name)}/${slug(sub)}`);
376 if (activeItem) return itemRefs.current[`/${slug(category.name)}/${slug(activeItem)}`];
377 }
378 return null;
379 }, [location.pathname, pendingActivePath]);
380
381 const updateLinePosition = useCallback(el => {
382 if (!el || !sidebarRef.current?.offsetParent) return null;
383 const sidebarRect = sidebarRef.current.getBoundingClientRect();
384 const elRect = el.getBoundingClientRect();
385 return elRect.top - sidebarRect.top + elRect.height / 2;
386 }, []);
387
388 const scrollActiveItemIntoView = useCallback(() => {
389 const activeEl = findActiveElement();
390 if (!activeEl || !sidebarContainerRef.current) return;
391
392 const containerRect = sidebarContainerRef.current.getBoundingClientRect();
393 const elementRect = activeEl.getBoundingClientRect();
394
395 const isOutOfView =
396 elementRect.top < containerRect.top + SCROLL_OFFSET || elementRect.bottom > containerRect.bottom - SCROLL_OFFSET;
397
398 if (isOutOfView) {
399 sidebarContainerRef.current.scrollTo({
400 top: sidebarContainerRef.current.scrollTop + (elementRect.top - containerRect.top) - SCROLL_OFFSET,
401 behavior: 'smooth'
402 });
403 }

Callers

nothing calls this directly

Calls 7

useSearchFunction · 0.90
useTransitionFunction · 0.90
useFavoritesSyncFunction · 0.85
useScrolledToBottomFunction · 0.85
toggleSearchFunction · 0.85
slugFunction · 0.70
scrollToTopFunction · 0.70

Tested by

no test coverage detected