Browse Source

fix table of contents button on publications and articles

master
silberengel 3 months ago
parent
commit
e8db4e89af
  1. 97
      src/lib/components/publications/Publication.svelte
  2. 11
      src/lib/components/publications/TableOfContents.svelte
  3. 14
      src/lib/components/util/ArticleNav.svelte

97
src/lib/components/publications/Publication.svelte

@ -8,7 +8,6 @@
SidebarWrapper, SidebarWrapper,
Heading, Heading,
CloseButton, CloseButton,
uiHelpers,
} from "flowbite-svelte"; } from "flowbite-svelte";
import { getContext, onDestroy, onMount } from "svelte"; import { getContext, onDestroy, onMount } from "svelte";
import { import {
@ -227,9 +226,6 @@
let currentBlogEvent: null | NDKEvent = $state(null); let currentBlogEvent: null | NDKEvent = $state(null);
const isLeaf = $derived(indexEvent.kind === 30041); const isLeaf = $derived(indexEvent.kind === 30041);
const tocSidebarUi = uiHelpers();
const closeTocSidebar = tocSidebarUi.close;
const isTocOpen = $state($publicationColumnVisibility.toc);
function isInnerActive() { function isInnerActive() {
return currentBlog !== null && $publicationColumnVisibility.inner; return currentBlog !== null && $publicationColumnVisibility.inner;
@ -472,7 +468,7 @@
<!-- Add gap & items-start so sticky sidebars size correctly --> <!-- Add gap & items-start so sticky sidebars size correctly -->
<div <div
class="relative grid gap-4 items-start grid-cols-[1fr_3fr_1fr] grid-rows-[auto_1fr]" class="relative grid gap-4 items-start grid-cols-[1fr_1fr] grid-rows-[auto_1fr]"
> >
<!-- Full-width ArticleNav row --> <!-- Full-width ArticleNav row -->
<ArticleNav {publicationType} rootId={indexEvent.id} {indexEvent} /> <ArticleNav {publicationType} rootId={indexEvent.id} {indexEvent} />
@ -494,46 +490,7 @@
/> />
<!-- Three-column row --> <!-- Three-column row -->
<div class="contents"> <div class="contents">
<!-- Table of contents --> <!-- Table of contents column removed - using overlay drawer instead -->
<div
class="mt-[70px] relative {$publicationColumnVisibility.toc
? 'w-64'
: 'w-auto'}"
>
{#if publicationType !== "blog" && !isLeaf}
{#if $publicationColumnVisibility.toc}
<Sidebar
class="z-10 ml-2 fixed top-[162px] max-h-[calc(100vh-165px)] overflow-y-auto dark:bg-primary-900 bg-primary-50 rounded"
activeUrl={`#${activeAddress ?? ""}`}
classes={{
div: "dark:bg-primary-900 bg-primary-50",
active: "bg-primary-100 dark:bg-primary-800 p-2 rounded-lg",
nonactive: "bg-primary-50 dark:bg-primary-900",
}}
>
<SidebarWrapper>
<CloseButton
color="secondary"
class="m-2 dark:text-primary-100"
onclick={closeToc}
></CloseButton>
<TableOfContents
{rootAddress}
{toc}
depth={2}
onSectionFocused={(address: string) =>
publicationTree.setBookmark(address)}
onLoadMore={() => {
if (!isLoading && !isDone && publicationTree) {
loadMore(4);
}
}}
/>
</SidebarWrapper>
</Sidebar>
{/if}
{/if}
</div>
<div class="mt-[70px]"> <div class="mt-[70px]">
<!-- Default publications --> <!-- Default publications -->
{#if $publicationColumnVisibility.main} {#if $publicationColumnVisibility.main}
@ -799,6 +756,56 @@
</div> </div>
</div> </div>
<!-- Table of Contents Drawer (overlay, works on mobile and desktop) -->
{#if publicationType !== "blog" && !isLeaf}
<!-- Backdrop overlay -->
<div
class="fixed inset-0 bg-black/50 z-[100] transition-opacity duration-300 {$publicationColumnVisibility.toc
? 'opacity-100 pointer-events-auto'
: 'opacity-0 pointer-events-none'}"
onclick={closeToc}
role="button"
tabindex="0"
onkeydown={(e) => {
if (e.key === 'Escape' || e.key === 'Enter' || e.key === ' ') {
closeToc();
}
}}
></div>
<!-- Drawer -->
<div
class="fixed top-[162px] left-0 h-[calc(100vh-162px)] w-fit min-w-[280px] max-w-[min(98vw,500px)] z-[110] dark:bg-primary-900 bg-primary-50 rounded-r-lg shadow-xl transition-transform duration-300 ease-in-out {$publicationColumnVisibility.toc
? 'translate-x-0'
: '-translate-x-full'}"
>
<div class="h-full flex flex-col overflow-hidden">
<div class="flex-shrink-0 p-2 border-b border-gray-200 dark:border-gray-700">
<CloseButton
color="secondary"
class="dark:text-primary-100"
onclick={closeToc}
></CloseButton>
</div>
<div class="flex-1 overflow-y-auto overflow-x-visible px-2 w-full">
<TableOfContents
{rootAddress}
{toc}
depth={2}
onSectionFocused={(address: string) =>
publicationTree.setBookmark(address)}
onLoadMore={() => {
if (!isLoading && !isDone && publicationTree) {
loadMore(4);
}
}}
onClose={closeToc}
/>
</div>
</div>
</div>
{/if}
<!-- Highlight Layer Component --> <!-- Highlight Layer Component -->
<HighlightLayer <HighlightLayer
bind:this={highlightLayerRef} bind:this={highlightLayerRef}

11
src/lib/components/publications/TableOfContents.svelte

@ -12,12 +12,13 @@
import Self from "./TableOfContents.svelte"; import Self from "./TableOfContents.svelte";
import { onMount, onDestroy } from "svelte"; import { onMount, onDestroy } from "svelte";
let { depth, onSectionFocused, onLoadMore, toc } = $props<{ let { depth, onSectionFocused, onLoadMore, onClose, toc } = $props<{
rootAddress: string; rootAddress: string;
depth: number; depth: number;
toc: TableOfContents; toc: TableOfContents;
onSectionFocused?: (address: string) => void; onSectionFocused?: (address: string) => void;
onLoadMore?: () => void; onLoadMore?: () => void;
onClose?: () => void;
}>(); }>();
let entries = $derived.by<TocEntry[]>(() => { let entries = $derived.by<TocEntry[]>(() => {
@ -59,6 +60,9 @@
onSectionFocused?.(address); onSectionFocused?.(address);
// Close the drawer after navigation
onClose?.();
// Check if this is the last entry and trigger loading more events // Check if this is the last entry and trigger loading more events
const currentEntries = entries; const currentEntries = entries;
const lastEntry = currentEntries[currentEntries.length - 1]; const lastEntry = currentEntries[currentEntries.length - 1];
@ -172,10 +176,11 @@
{@const childDepth = depth + 1} {@const childDepth = depth + 1}
<SidebarDropdownWrapper <SidebarDropdownWrapper
label={entry.title} label={entry.title}
btnClass="flex items-center p-2 w-full font-normal text-gray-900 rounded-lg transition duration-75 group hover:bg-primary-50 dark:text-white dark:hover:bg-primary-800 {isVisible ? 'toc-highlight' : ''} " btnClass="flex items-center p-2 w-full font-normal text-gray-900 rounded-lg transition duration-75 group hover:bg-primary-50 dark:text-white dark:hover:bg-primary-800 {isVisible ? 'toc-highlight' : ''} whitespace-nowrap min-w-fit"
class="w-full"
bind:isOpen={() => expanded, (open) => setEntryExpanded(address, open)} bind:isOpen={() => expanded, (open) => setEntryExpanded(address, open)}
> >
<Self rootAddress={address} depth={childDepth} {toc} {onSectionFocused} {onLoadMore} /> <Self rootAddress={address} depth={childDepth} {toc} {onSectionFocused} {onLoadMore} {onClose} />
</SidebarDropdownWrapper> </SidebarDropdownWrapper>
{/if} {/if}
{/each} {/each}

14
src/lib/components/util/ArticleNav.svelte

@ -152,7 +152,7 @@
</script> </script>
<nav <nav
class="Navbar navbar-leather col-span-3 flex fixed top-[100px] sm:top-[92px] w-full min-h-[70px] px-2 sm:px-4 py-2.5 z-10 transition-transform duration-300 {isVisible class="Navbar navbar-leather col-span-2 flex fixed top-[100px] sm:top-[92px] w-full min-h-[70px] px-2 sm:px-4 py-2.5 z-10 transition-transform duration-300 {isVisible
? 'translate-y-0' ? 'translate-y-0'
: '-translate-y-full'}" : '-translate-y-full'}"
> >
@ -171,21 +171,21 @@
{#if isIndexEvent} {#if isIndexEvent}
{#if publicationType === "blog"} {#if publicationType === "blog"}
<Button <Button
class={`btn-leather hidden sm:flex !w-auto ${$publicationColumnVisibility.blog ? "active" : ""}`} class={`btn-leather !w-auto ${$publicationColumnVisibility.blog ? "active" : ""}`}
outline={true} outline={true}
onclick={() => toggleColumn("blog")} onclick={() => toggleColumn("blog")}
title="Table of Contents"
> >
<BookOutline class="!fill-none inline mr-1" /> <BookOutline class="!fill-none" />
<span class="hidden sm:inline">Table of Contents</span>
</Button> </Button>
{:else if !$publicationColumnVisibility.discussion && !$publicationColumnVisibility.toc} {:else if !$publicationColumnVisibility.discussion}
<Button <Button
class={`btn-leather !w-auto ${$publicationColumnVisibility.toc ? "active" : ""}`} class={`btn-leather !w-auto ${$publicationColumnVisibility.toc ? "active" : ""}`}
outline={true} outline={true}
onclick={() => toggleColumn("toc")} onclick={() => toggleColumn("toc")}
title="Table of Contents"
> >
<BookOutline class="!fill-none inline mr-1" /> <BookOutline class="!fill-none" />
<span class="hidden sm:inline">Table of Contents</span>
</Button> </Button>
{/if} {/if}
{/if} {/if}

Loading…
Cancel
Save