From f34f5ef7159cba855a78b1b32332458f139940e6 Mon Sep 17 00:00:00 2001 From: Kenneth Date: Mon, 2 Jun 2025 17:56:15 +0100 Subject: [PATCH] refactor side nav to make it composable --- packages/web/src/app/-side-nav.tsx | 43 ---------------------- packages/web/src/app/bookmarks/index.tsx | 26 ++++++++++--- packages/web/src/app/collections/index.tsx | 25 +++++++++++-- packages/web/src/components/side-nav.tsx | 27 ++++++++++++++ 4 files changed, 70 insertions(+), 51 deletions(-) delete mode 100644 packages/web/src/app/-side-nav.tsx create mode 100644 packages/web/src/components/side-nav.tsx diff --git a/packages/web/src/app/-side-nav.tsx b/packages/web/src/app/-side-nav.tsx deleted file mode 100644 index 2b16ab9..0000000 --- a/packages/web/src/app/-side-nav.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Link, useRouterState, useNavigate } from "@tanstack/react-router" -import { useMnemonics } from "~/hooks/use-mnemonics" - -function SideNav({ enableMnemonics }: { enableMnemonics: boolean }) { - const navigate = useNavigate() - - useMnemonics( - { - b: () => navigate({ to: "/bookmarks" }), - c: () => navigate({ to: "/collections" }), - }, - { ignore: () => !enableMnemonics }, - ) - - return ( - - ) -} - -function NavItem({ to, label }: { to: string; label: string }) { - const currentPath = useRouterState({ select: (state) => state.location.pathname }) - - return ( -
  • - - [{currentPath === to ? "•" : " "}]{" "} - - {label.charAt(0)} - {label.substring(1)} - - -
  • - ) -} - -export { SideNav } diff --git a/packages/web/src/app/bookmarks/index.tsx b/packages/web/src/app/bookmarks/index.tsx index 3559ce3..019c955 100644 --- a/packages/web/src/app/bookmarks/index.tsx +++ b/packages/web/src/app/bookmarks/index.tsx @@ -9,11 +9,11 @@ import { useTags } from "~/bookmark/api.ts" import { Button } from "~/components/button" import { LoadingSpinner } from "~/components/loading-spinner" import { Message, MessageVariant } from "~/components/message.tsx" +import { SideNav, SideNavItem } from "~/components/side-nav" import { useDocumentEvent } from "~/hooks/use-document-event.ts" import { useMnemonics } from "~/hooks/use-mnemonics.ts" import { BookmarkList } from "./-bookmark-list" import { ActionBarContentKind, DialogKind, WindowKind, useBookmarkPageStore } from "./-store" -import { SideNav } from "~/app/-side-nav" export const Route = createFileRoute("/bookmarks/")({ component: RouteComponent, @@ -40,11 +40,27 @@ function BookmarkListPane() { } function _SideNav() { - const hasDialog = useBookmarkPageStore((state) => state.dialog.kind !== DialogKind.None) - const isSearchBarActive = useBookmarkPageStore( - (state) => state.actionBarContent.kind === ActionBarContentKind.SearchBar, + const navigate = useNavigate() + + useMnemonics( + { + b: () => navigate({ to: "/bookmarks" }), + c: () => navigate({ to: "/collections" }), + }, + { + ignore: () => { + const state = useBookmarkPageStore.getState() + return state.dialog.kind !== DialogKind.None || state.actionBarContent.kind === ActionBarContentKind.SearchBar + }, + }, + ) + + return ( + + + + ) - return } function BookmarkListContainer() { diff --git a/packages/web/src/app/collections/index.tsx b/packages/web/src/app/collections/index.tsx index c4dd310..0d8196b 100644 --- a/packages/web/src/app/collections/index.tsx +++ b/packages/web/src/app/collections/index.tsx @@ -6,12 +6,12 @@ import { useLogOut } from "~/auth" import { useCollections } from "~/collection/api" import { Button } from "~/components/button" import { LoadingSpinner } from "~/components/loading-spinner" +import { SideNav, SideNavItem } from "~/components/side-nav" import { useMnemonics } from "~/hooks/use-mnemonics" import { CollectionList } from "./-collection-list" import { AddCollectionDialog } from "./-dialogs/add-collection-dialog" import { DeleteCollectionDialog } from "./-dialogs/delete-collection-dialog" import { DialogKind, WindowKind, useCollectionPageStore } from "./-store" -import { SideNav } from "~/app/-side-nav" export const Route = createFileRoute("/collections/")({ component: CollectionsPage, @@ -52,8 +52,27 @@ function CollectionsPane() { } function _SideNav() { - const hasDialog = useCollectionPageStore((state) => state.dialog.kind !== DialogKind.None) - return + const navigate = useNavigate() + + useMnemonics( + { + b: () => navigate({ to: "/bookmarks" }), + c: () => navigate({ to: "/collections" }), + }, + { + ignore: () => { + const state = useCollectionPageStore.getState() + return state.dialog.kind !== DialogKind.None + }, + }, + ) + + return ( + + + + + ) } function CollectionsContainer() { diff --git a/packages/web/src/components/side-nav.tsx b/packages/web/src/components/side-nav.tsx new file mode 100644 index 0000000..2f54d4f --- /dev/null +++ b/packages/web/src/components/side-nav.tsx @@ -0,0 +1,27 @@ +import { Link } from "@tanstack/react-router" + +function SideNav({ children }: { children: React.ReactNode }) { + return ( + + ) +} + +function SideNavItem({ to, label, active = false }: { to: string; label: string; active?: boolean }) { + return ( +
  • + + [{active ? "•" : " "}]{" "} + + {label.charAt(0)} + {label.substring(1)} + + +
  • + ) +} + +export { SideNav, SideNavItem }