diff options
author | buttercat1791 <mjjurkoic@gmail.com> | 2024-07-12 09:21:41 -0500 |
---|---|---|
committer | Silberengel <153727378+SilberWitch@users.noreply.github.com> | 2024-07-22 09:44:52 +0200 |
commit | 99d9943e267041f2effa2833d29f63929c163b45 (patch) | |
tree | d7efe51ec12d1882cb4472c6302653db8882cfb1 /src/lib | |
parent | 2fd22b6039b1c10b362b976393dd2e7501cf065e (diff) |
Handle in-article hash path navigation
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/Article.svelte | 79 |
1 files changed, 42 insertions, 37 deletions
diff --git a/src/lib/Article.svelte b/src/lib/Article.svelte index 55839f8..f0548d5 100644 --- a/src/lib/Article.svelte +++ b/src/lib/Article.svelte @@ -16,25 +16,41 @@ return events.filter((event) => event != null); } - const converter = new showdown.Converter(); + function normalizeHashPath(str: string): string { + return str + .toLowerCase() + .replace(/\s+/g, '-') + .replace(/[^\w-]/g, ''); + } - const transitionParams = { - x: -320, - duration: 200, - easing: sineIn - }; + function scrollToElementWithOffset() { + const hash = window.location.hash; + if (hash) { + const targetElement = document.querySelector(hash); + if (targetElement) { + const headerOffset = 80; + const elementPosition = targetElement.getBoundingClientRect().top; + const offsetPosition = elementPosition + window.scrollY - headerOffset; + + window.scrollTo({ + top: offsetPosition, + behavior: 'auto', + }); + } + } + } - let width: number; - let breakpoint: number = 768; // Tailwind md breakpoint - let drawerHidden: boolean = false; - $: width >= breakpoint - ? drawerHidden = false - : drawerHidden = true; onMount(() => { - width >= breakpoint - ? drawerHidden = false - : drawerHidden = true; + window.addEventListener('hashchange', scrollToElementWithOffset); + // Also handle the case where the user lands on the page with a hash in the URL + scrollToElementWithOffset(); + + return () => { + window.removeEventListener('hashchange', scrollToElementWithOffset); + }; }); + + const converter = new showdown.Converter(); </script> {#await getEvents()} @@ -49,12 +65,12 @@ <!-- TODO: Handle hash paths for navigation within the article. --> <Sidebar class='sidebar-leather fixed top-20 left-0 px-4 w-60' {activeHash}> <SidebarWrapper> - <SidebarGroup> + <SidebarGroup class='sidebar-group-leather overflow-y-scroll'> {#each events as event} <SidebarItem class='sidebar-item-leather' label={event.getMatchingTags('title')[0][1]} - href={`${$page.url.pathname}#${event.getMatchingTags('title')[0][1]}`} + href={`${$page.url.pathname}#${normalizeHashPath(event.getMatchingTags('title')[0][1])}`} /> {/each} </SidebarGroup> @@ -63,7 +79,13 @@ <div class='flex flex-col space-y-4 max-w-2xl'> {#each events as event} <div class='note-leather flex flex-col space-y-2'> - <Heading tag='h3' class='h-leather'>{event.getMatchingTags('title')[0][1]}</Heading> + <Heading + tag='h3' + class='h-leather' + id={normalizeHashPath(event.getMatchingTags('title')[0][1])} + > + {event.getMatchingTags('title')[0][1]} + </Heading> {@html converter.makeHtml(event.content)} </div> {/each} @@ -71,24 +93,7 @@ {/await} <style> - .article { - display: flex; - padding: 1rem; - } - .toc { - padding: 3%; - min-width: 5%; - padding-top: 1%; - border: 1px white solid; - border-radius: 10px; - border-top-width: 5px; - } - .article-content { - min-width: 80%; - max-width: 85%; - padding: 1%; - border: 1px white solid; - border-radius: 10px; - border-top-width: 5px; + :global(.sidebar-group-leather) { + max-height: calc(100vh - 8rem); } </style> |