Skip to content

Commit

Permalink
feature: auto scroll to the selected week in sidebar and closing side…
Browse files Browse the repository at this point in the history
…bar on ESC
  • Loading branch information
akhil committed Oct 30, 2024
1 parent 0c553e9 commit d378446
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,19 @@ export function Sidebar({
}
};

// listen for ESC key and close the sidebar
const handleEscape = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
closeSidebar();
}
};

document.addEventListener('mousedown', handleClickOutside);
document.addEventListener('keydown', handleEscape);

return () => {
document.removeEventListener('mousedown', handleClickOutside);
document.removeEventListener('keydown', handleEscape);
};
}, [sidebarRef]);

Expand Down Expand Up @@ -129,6 +138,24 @@ export function Sidebar({
[courseId, findPathToContent, fullCourseContent],
);

const activeItemRef = useRef<HTMLDivElement | HTMLAnchorElement | null>(null);

useEffect(() => {
if (sidebarOpen && activeItemRef.current) {
activeItemRef.current.scrollIntoView({ behavior: 'smooth', block: 'center' });
// focus on the active item
if (activeItemRef.current instanceof HTMLAnchorElement) {
activeItemRef.current.focus();
} else if (activeItemRef.current instanceof HTMLDivElement) {
// check for the first focusable element and focus on it
const firstFocusableElement = activeItemRef.current.querySelector('button, a');
if (firstFocusableElement) {
(firstFocusableElement as HTMLButtonElement | HTMLAnchorElement).focus();
}
}
}
}, [sidebarOpen]);

const renderContent = useCallback(
(contents: FullCourseContent[]) => {
return contents.map((content) => {
Expand All @@ -140,6 +167,7 @@ export function Sidebar({
key={content.id}
value={`item-${content.id}`}
className={`rounded-md border-none ${isActiveContent ? 'bg-primary/5' : ''}`}
ref={isActiveContent ? (activeItemRef as React.RefObject<HTMLDivElement>) : null}
>
<AccordionTrigger className="rounded-md px-4 text-lg font-medium capitalize">
{content.title}
Expand All @@ -156,6 +184,7 @@ export function Sidebar({
key={content.id}
href={navigateToContent(content.id) || '#'}
className={`flex w-full cursor-pointer items-center rounded-md p-4 tracking-tight hover:bg-primary/10 ${isActiveContent ? 'bg-primary/10' : ''}`}
ref={isActiveContent ? (activeItemRef as React.RefObject<HTMLAnchorElement>) : null}
>
<div className="flex w-full items-center justify-between gap-2">
<div className="flex items-center gap-2">
Expand Down Expand Up @@ -217,7 +246,7 @@ export function Sidebar({
<X className="size-5" />
</Button>
</div>
<Accordion type="multiple" className="w-full px-4 capitalize">
<Accordion type="multiple" defaultValue={currentActiveContentIds.map(num => `item-${num}`)} className="w-full px-4 capitalize">
{memoizedContent}
</Accordion>
</motion.div>
Expand Down

0 comments on commit d378446

Please sign in to comment.