Optimize navigation links
This commit is contained in:
parent
346a5a0005
commit
fb8a8b2224
4 changed files with 50 additions and 14 deletions
|
|
@ -8,9 +8,11 @@
|
||||||
type Props = {
|
type Props = {
|
||||||
mode: "simple" | "full";
|
mode: "simple" | "full";
|
||||||
activeRoom?: string;
|
activeRoom?: string;
|
||||||
|
activeResource?: string;
|
||||||
|
contactsActive?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
let { mode, activeRoom }: Props = $props();
|
let { mode, activeRoom, activeResource, contactsActive }: Props = $props();
|
||||||
|
|
||||||
// The description of the room currently being viewed (full mode).
|
// The description of the room currently being viewed (full mode).
|
||||||
const activeAbout = $derived(
|
const activeAbout = $derived(
|
||||||
|
|
@ -26,7 +28,7 @@
|
||||||
href="/"
|
href="/"
|
||||||
class="flex items-center gap-2 py-1 hover:bg-neutral-100 text-neutral-700"
|
class="flex items-center gap-2 py-1 hover:bg-neutral-100 text-neutral-700"
|
||||||
>
|
>
|
||||||
Home
|
{mode === "simple" ? "Discussions" : "Home"}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{#if mode === "simple"}
|
{#if mode === "simple"}
|
||||||
|
|
@ -74,13 +76,17 @@
|
||||||
{#each resourcesStore.list as r (r.slug)}
|
{#each resourcesStore.list as r (r.slug)}
|
||||||
<a
|
<a
|
||||||
href="/resource/{r.slug}"
|
href="/resource/{r.slug}"
|
||||||
class="block py-1 text-neutral-500 hover:text-neutral-900"
|
aria-current={activeResource === r.slug ? "page" : undefined}
|
||||||
|
class="block py-1 hover:text-neutral-900
|
||||||
|
{activeResource === r.slug ? 'text-brand' : 'text-neutral-500'}"
|
||||||
>{r.title}</a
|
>{r.title}</a
|
||||||
>
|
>
|
||||||
{/each}
|
{/each}
|
||||||
<a
|
<a
|
||||||
href="/contacts"
|
href="/contacts"
|
||||||
class="block py-1 text-neutral-500 hover:text-neutral-900">Contacts</a
|
aria-current={contactsActive ? "page" : undefined}
|
||||||
|
class="block py-1 hover:text-neutral-900
|
||||||
|
{contactsActive ? 'text-brand' : 'text-neutral-500'}">Contacts</a
|
||||||
>
|
>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,18 @@
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
mode: "simple" | "full";
|
mode: "simple" | "full";
|
||||||
activeRoom?: string;
|
activeRoom?: string;
|
||||||
|
activeResource?: string;
|
||||||
|
contactsActive?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
let { open, onClose, mode, activeRoom }: Props = $props();
|
let {
|
||||||
|
open,
|
||||||
|
onClose,
|
||||||
|
mode,
|
||||||
|
activeRoom,
|
||||||
|
activeResource,
|
||||||
|
contactsActive,
|
||||||
|
}: Props = $props();
|
||||||
|
|
||||||
function onLogin() {
|
function onLogin() {
|
||||||
onClose();
|
onClose();
|
||||||
|
|
@ -110,7 +119,8 @@
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
||||||
onclick={onClose}
|
onclick={onClose}
|
||||||
class="py-2 text-xl text-neutral-700 hover:text-brand">Home</a
|
class="py-2 text-xl text-neutral-700 hover:text-brand"
|
||||||
|
>{mode === "simple" ? "Discussions" : "Home"}</a
|
||||||
>
|
>
|
||||||
|
|
||||||
{#if mode === "full"}
|
{#if mode === "full"}
|
||||||
|
|
@ -146,14 +156,18 @@
|
||||||
<a
|
<a
|
||||||
href="/resource/{r.slug}"
|
href="/resource/{r.slug}"
|
||||||
onclick={onClose}
|
onclick={onClose}
|
||||||
class="block py-1.5 text-xl text-neutral-700 hover:text-brand"
|
aria-current={activeResource === r.slug ? "page" : undefined}
|
||||||
|
class="block py-1.5 text-xl hover:text-brand
|
||||||
|
{activeResource === r.slug ? 'text-brand' : 'text-neutral-700'}"
|
||||||
>{r.title}</a
|
>{r.title}</a
|
||||||
>
|
>
|
||||||
{/each}
|
{/each}
|
||||||
<a
|
<a
|
||||||
href="/contacts"
|
href="/contacts"
|
||||||
onclick={onClose}
|
onclick={onClose}
|
||||||
class="block py-1.5 text-lg text-neutral-700 hover:text-brand"
|
aria-current={contactsActive ? "page" : undefined}
|
||||||
|
class="block py-1.5 text-lg hover:text-brand
|
||||||
|
{contactsActive ? 'text-brand' : 'text-neutral-700'}"
|
||||||
>Contacts</a
|
>Contacts</a
|
||||||
>
|
>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,11 @@
|
||||||
<header
|
<header
|
||||||
class="sticky top-0 z-20 flex h-16 shrink-0 items-center justify-between gap-2 bg-neutral-100 px-4 md:static md:px-8"
|
class="sticky top-0 z-20 flex h-16 shrink-0 items-center justify-between gap-2 bg-neutral-100 px-4 md:static md:px-8"
|
||||||
>
|
>
|
||||||
<div class="flex min-w-0 items-center gap-2">
|
<a
|
||||||
|
href="/"
|
||||||
|
class="flex min-w-0 items-center gap-2 hover:opacity-90"
|
||||||
|
aria-label="{name} — home"
|
||||||
|
>
|
||||||
{#if groupStore.data?.picture}
|
{#if groupStore.data?.picture}
|
||||||
<img
|
<img
|
||||||
src={groupStore.data.picture}
|
src={groupStore.data.picture}
|
||||||
|
|
@ -32,7 +36,7 @@
|
||||||
<span class="truncate text-2xl font-medium text-neutral-900 md:text-[1.7rem]"
|
<span class="truncate text-2xl font-medium text-neutral-900 md:text-[1.7rem]"
|
||||||
>{name}</span
|
>{name}</span
|
||||||
>
|
>
|
||||||
</div>
|
</a>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={onMenuToggle}
|
onclick={onMenuToggle}
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,22 @@
|
||||||
let mobileView = $state<"forum" | "chat">("forum");
|
let mobileView = $state<"forum" | "chat">("forum");
|
||||||
|
|
||||||
// Room pages highlight via their slug; thread pages highlight the room the
|
// Room pages highlight via their slug; thread pages highlight the room the
|
||||||
// thread belongs to (tracked in activeGroup).
|
// thread belongs to (tracked in activeGroup). Scoped to those routes so a
|
||||||
|
// resource slug (same [slug] param name) never highlights a room.
|
||||||
const activeRoom = $derived(
|
const activeRoom = $derived(
|
||||||
page.params.slug ??
|
page.url.pathname.startsWith("/room/")
|
||||||
(page.url.pathname.startsWith("/thread/") ? activeGroup.id : ""),
|
? (page.params.slug ?? "")
|
||||||
|
: page.url.pathname.startsWith("/thread/")
|
||||||
|
? activeGroup.id
|
||||||
|
: "",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Resource pages highlight the open article in the Resources menu.
|
||||||
|
const activeResource = $derived(
|
||||||
|
page.url.pathname.startsWith("/resource/") ? (page.params.slug ?? "") : "",
|
||||||
|
);
|
||||||
|
const contactsActive = $derived(page.url.pathname === "/contacts");
|
||||||
|
|
||||||
// Article pages (both modes) and the full-mode landing have no single room to
|
// Article pages (both modes) and the full-mode landing have no single room to
|
||||||
// chat in, so they render the latest-discussions panel instead of room chat.
|
// chat in, so they render the latest-discussions panel instead of room chat.
|
||||||
// The simple-mode home keeps its room chat, like every full-mode room.
|
// The simple-mode home keeps its room chat, like every full-mode room.
|
||||||
|
|
@ -93,7 +103,7 @@
|
||||||
? 'flex flex-1 overflow-hidden'
|
? 'flex flex-1 overflow-hidden'
|
||||||
: ''}"
|
: ''}"
|
||||||
>
|
>
|
||||||
<LeftSidebar {mode} {activeRoom} />
|
<LeftSidebar {mode} {activeRoom} {activeResource} {contactsActive} />
|
||||||
<main
|
<main
|
||||||
class="min-h-[calc(100dvh_-_4rem)] bg-white px-6 pt-8 pb-20 shadow-lg md:min-h-0 md:overflow-y-auto md:rounded-t-xl md:px-10 md:pt-6 {showDiscussions
|
class="min-h-[calc(100dvh_-_4rem)] bg-white px-6 pt-8 pb-20 shadow-lg md:min-h-0 md:overflow-y-auto md:rounded-t-xl md:px-10 md:pt-6 {showDiscussions
|
||||||
? 'md:flex-[3]'
|
? 'md:flex-[3]'
|
||||||
|
|
@ -181,6 +191,8 @@
|
||||||
onClose={() => (menuOpen = false)}
|
onClose={() => (menuOpen = false)}
|
||||||
{mode}
|
{mode}
|
||||||
{activeRoom}
|
{activeRoom}
|
||||||
|
{activeResource}
|
||||||
|
{contactsActive}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<LoginModal />
|
<LoginModal />
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue