aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar buttercat1791 <mjjurkoic@gmail.com>2024-07-16 09:46:47 -0500
committerLibravatar Silberengel <153727378+SilberWitch@users.noreply.github.com>2024-07-22 09:44:52 +0200
commita043e33909e71e139b8e4357119df79613d4b7a1 (patch)
treece035ebfe42465b45ac2a7275915823b380b32cb
parent99d9943e267041f2effa2833d29f63929c163b45 (diff)
Add collapsible left menu to navbar
-rw-r--r--src/lib/Article.svelte75
-rw-r--r--src/lib/components/Navigation.svelte10
-rw-r--r--src/lib/stores.ts5
3 files changed, 66 insertions, 24 deletions
diff --git a/src/lib/Article.svelte b/src/lib/Article.svelte
index f0548d5..48c9105 100644
--- a/src/lib/Article.svelte
+++ b/src/lib/Article.svelte
@@ -1,11 +1,10 @@
<script lang="ts">
import { ndk } from '$lib/ndk';
- import { idList } from '$lib/stores';
+ import { idList, isLeftHamburgerMenuInUse, leftHamburgerMenuHrefs, leftHamburgerMenuItems } from '$lib/stores';
import type { NDKEvent } from '@nostr-dev-kit/ndk';
import { page } from '$app/stores';
import { Heading, Sidebar, SidebarGroup, SidebarItem, SidebarWrapper, Skeleton, TextPlaceholder } from 'flowbite-svelte';
import showdown from 'showdown';
- import { sineIn } from 'svelte/easing';
import { onMount } from 'svelte';
$: activeHash = $page.url.hash;
@@ -13,7 +12,25 @@
async function getEvents(): Promise<NDKEvent[]> {
const eventPromises = $idList.map(async (id) => await $ndk.fetchEvent(id));
const events = await Promise.all(eventPromises);
- return events.filter((event) => event != null);
+
+ const filteredEvents = events.filter((event) => event != null);
+
+ const eventNames: string[] = [];
+ const eventHrefs = new Map<string, string>();
+
+ filteredEvents.forEach(event => {
+ const title = event.getMatchingTags('title')[0][1];
+
+ eventNames.push(title);
+
+ const normalizedTitle = normalizeHashPath(title);
+ eventHrefs.set(title, `${$page.url.pathname}#${normalizedTitle}`);
+ });
+
+ leftHamburgerMenuItems.set(eventNames);
+ leftHamburgerMenuHrefs.set(eventHrefs);
+
+ return filteredEvents;
}
function normalizeHashPath(str: string): string {
@@ -40,13 +57,21 @@
}
}
+ const sidebarBreakpointWidth = 1140;
+ const setLeftHamburgerMenuInUse = () => {
+ isLeftHamburgerMenuInUse.set(window.innerWidth < sidebarBreakpointWidth ? true : false);
+ };
+
onMount(() => {
window.addEventListener('hashchange', scrollToElementWithOffset);
// Also handle the case where the user lands on the page with a hash in the URL
scrollToElementWithOffset();
+ window.addEventListener('resize', setLeftHamburgerMenuInUse);
+
return () => {
window.removeEventListener('hashchange', scrollToElementWithOffset);
+ window.removeEventListener('resize', setLeftHamburgerMenuInUse);
};
});
@@ -54,28 +79,30 @@
</script>
{#await getEvents()}
- <Sidebar class='sidebar-leather fixed top-20 left-0 px-4 w-60'>
- <SidebarWrapper>
- <Skeleton/>
- </SidebarWrapper>
- </Sidebar>
- <TextPlaceholder class='max-w-2xl'/>
+ {#if !$isLeftHamburgerMenuInUse}
+ <Sidebar class='sidebar-leather fixed top-20 left-0 px-4 w-60'>
+ <SidebarWrapper>
+ <Skeleton/>
+ </SidebarWrapper>
+ </Sidebar>
+ <TextPlaceholder class='max-w-2xl'/>
+ {/if}
{:then events}
- <!-- TODO: Collapse the sidebar when the page gets below a certain width. -->
- <!-- 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 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}#${normalizeHashPath(event.getMatchingTags('title')[0][1])}`}
- />
- {/each}
- </SidebarGroup>
- </SidebarWrapper>
- </Sidebar>
+ {#if !$isLeftHamburgerMenuInUse}
+ <Sidebar class='sidebar-leather fixed top-20 left-0 px-4 w-60' {activeHash}>
+ <SidebarWrapper>
+ <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}#${normalizeHashPath(event.getMatchingTags('title')[0][1])}`}
+ />
+ {/each}
+ </SidebarGroup>
+ </SidebarWrapper>
+ </Sidebar>
+ {/if}
<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'>
diff --git a/src/lib/components/Navigation.svelte b/src/lib/components/Navigation.svelte
index d91e3a0..88f4cb5 100644
--- a/src/lib/components/Navigation.svelte
+++ b/src/lib/components/Navigation.svelte
@@ -1,11 +1,21 @@
<script lang="ts">
+ import { isLeftHamburgerMenuInUse, leftHamburgerMenuHrefs, leftHamburgerMenuItems } from '$lib/stores';
import { DarkMode, Navbar, NavLi, NavUl, NavHamburger, NavBrand } from 'flowbite-svelte';
+ import { get } from 'svelte/store';
let className: string;
export { className as class };
</script>
<Navbar class={`Navbar navbar-leather ${className}`}>
+ {#if $isLeftHamburgerMenuInUse}
+ <NavHamburger class='btn-leather' />
+ <NavUl class='ul-leather'>
+ {#each $leftHamburgerMenuItems as menuItem}
+ <NavLi href={$leftHamburgerMenuHrefs.get(menuItem)}>{menuItem}</NavLi>
+ {/each}
+ </NavUl>
+ {/if}
<div class='flex flex-grow justify-between'>
<NavBrand href='./'>
<h1 class='font-serif'>Alexandria</h1>
diff --git a/src/lib/stores.ts b/src/lib/stores.ts
index 67238dc..fa9a242 100644
--- a/src/lib/stores.ts
+++ b/src/lib/stores.ts
@@ -1,3 +1,8 @@
import { writable } from "svelte/store";
export let idList = writable<string[]>([]);
+
+export const isLeftHamburgerMenuInUse = writable(false);
+
+export const leftHamburgerMenuItems = writable<string[]>([]);
+export const leftHamburgerMenuHrefs = writable<Map<string, string>>(new Map());