feat(ui): add scroll area component and navigation enhancements
Add ScrollArea UI component using Radix UI for better content scrolling. Enhance header navigation with back button and conditional home button display. Update dependencies including @radix-ui/react-scroll-area and reorganize @nontara/server.
This commit is contained in:
@@ -9,9 +9,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nontara/language-codes": "workspace:*",
|
||||
"@nontara/server": "workspace:*",
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
@@ -26,7 +28,6 @@
|
||||
"@trpc/client": "^11.5.0",
|
||||
"@trpc/server": "^11.5.0",
|
||||
"@trpc/tanstack-react-query": "^11.5.0",
|
||||
"@nontara/server": "workspace:*",
|
||||
"better-auth": "^1.3.10",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Link, useRouterState } from "@tanstack/react-router";
|
||||
import { Link, useRouter, useRouterState } from "@tanstack/react-router";
|
||||
import {
|
||||
ArrowLeft,
|
||||
Folder,
|
||||
FolderTree,
|
||||
Home,
|
||||
@@ -115,8 +116,9 @@ NavigationSheetContent.displayName = "NavigationSheetContent";
|
||||
function HeaderBar() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const handleNavigate = useCallback(() => setOpen(false), []);
|
||||
const router = useRouterState();
|
||||
const pathname = router.location.pathname;
|
||||
const router = useRouter();
|
||||
const routerState = useRouterState();
|
||||
const pathname = routerState.location.pathname;
|
||||
|
||||
if (pathname.endsWith("dashboard") || pathname.endsWith("dashboard/")) {
|
||||
return;
|
||||
@@ -125,6 +127,30 @@ function HeaderBar() {
|
||||
return (
|
||||
<header className="sticky top-0 z-50 flex items-center justify-between border-border border-b bg-muted/95 px-5 py-3 shadow-sm backdrop-blur supports-[backdrop-filter]:bg-muted/80">
|
||||
<div className="flex items-center gap-3">
|
||||
{pathname !== "/home" && (
|
||||
<>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
aria-label="Go back"
|
||||
onClick={() => router.history.back()}
|
||||
>
|
||||
<ArrowLeft className="size-5" aria-hidden="true" />
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
aria-label="Go to home"
|
||||
asChild
|
||||
>
|
||||
<Link to="/home">
|
||||
<Home className="size-5" aria-hidden="true" />
|
||||
</Link>
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Sheet open={open} onOpenChange={setOpen}>
|
||||
<SheetTrigger asChild>
|
||||
<Button
|
||||
@@ -141,15 +167,19 @@ function HeaderBar() {
|
||||
<NavigationSheetContent onNavigate={handleNavigate} />
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
<img
|
||||
src={logoSrc}
|
||||
alt="Nontara logo"
|
||||
className="h-9 w-auto select-none"
|
||||
loading="eager"
|
||||
fetchPriority="high"
|
||||
decoding="async"
|
||||
draggable={false}
|
||||
/>
|
||||
{pathname === "/home" && (
|
||||
<Link to="/home" className="flex items-center">
|
||||
<img
|
||||
src={logoSrc}
|
||||
alt="Nontara logo"
|
||||
className="h-9 w-auto select-none"
|
||||
loading="eager"
|
||||
fetchPriority="high"
|
||||
decoding="async"
|
||||
draggable={false}
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
|
||||
56
apps/web/src/components/ui/scroll-area.tsx
Normal file
56
apps/web/src/components/ui/scroll-area.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
||||
import type * as React from "react";
|
||||
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
function ScrollArea({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.Root
|
||||
data-slot="scroll-area"
|
||||
className={cn("relative", className)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.Viewport
|
||||
data-slot="scroll-area-viewport"
|
||||
className="size-full rounded-[inherit] outline-none transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] focus-visible:ring-ring/50"
|
||||
>
|
||||
{children}
|
||||
</ScrollAreaPrimitive.Viewport>
|
||||
<ScrollBar />
|
||||
<ScrollAreaPrimitive.Corner />
|
||||
</ScrollAreaPrimitive.Root>
|
||||
);
|
||||
}
|
||||
|
||||
function ScrollBar({
|
||||
className,
|
||||
orientation = "vertical",
|
||||
...props
|
||||
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.ScrollAreaScrollbar
|
||||
data-slot="scroll-area-scrollbar"
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"flex touch-none select-none p-px transition-colors",
|
||||
orientation === "vertical" &&
|
||||
"h-full w-2.5 border-l border-l-transparent",
|
||||
orientation === "horizontal" &&
|
||||
"h-2.5 flex-col border-t border-t-transparent",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ScrollAreaPrimitive.ScrollAreaThumb
|
||||
data-slot="scroll-area-thumb"
|
||||
className="relative flex-1 rounded-full bg-border"
|
||||
/>
|
||||
</ScrollAreaPrimitive.ScrollAreaScrollbar>
|
||||
);
|
||||
}
|
||||
|
||||
export { ScrollArea, ScrollBar };
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
||||
import type { TRPCOptionsProxy } from "@trpc/tanstack-react-query";
|
||||
import { ThemeProvider } from "next-themes";
|
||||
import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import type { AppRouter } from "../../../server/src/trpc";
|
||||
import appCss from "../index.css?url";
|
||||
@@ -57,11 +58,14 @@ function RootDocument() {
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
>
|
||||
<div className="grid h-svh grid-rows-[auto_1fr]">
|
||||
{/* <Header />
|
||||
{isFetching ? <Loader /> : <Outlet />} */}
|
||||
<Outlet />
|
||||
</div>
|
||||
<ScrollArea className="h-svh w-full">
|
||||
<div className="grid min-h-svh grid-rows-[auto_1fr]">
|
||||
{/* <Header />
|
||||
{isFetching ? <Loader /> : <Outlet />} */}
|
||||
<Outlet />
|
||||
</div>
|
||||
<ScrollBar orientation="vertical" />
|
||||
</ScrollArea>
|
||||
<Toaster richColors />
|
||||
</ThemeProvider>
|
||||
<TanStackRouterDevtools position="bottom-left" />
|
||||
|
||||
5
bun.lock
5
bun.lock
@@ -41,6 +41,7 @@
|
||||
"@radix-ui/react-avatar": "^1.1.10",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.7",
|
||||
"@radix-ui/react-slot": "^1.2.3",
|
||||
@@ -67,8 +68,8 @@
|
||||
"react-dom": "19.1.0",
|
||||
"sonner": "^2.0.3",
|
||||
"tailwind-merge": "^3.3.1",
|
||||
"tailwindcss": "^4.1.13",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"tailwindcss": "^4.1.3",
|
||||
"tw-animate-css": "^1.2.5",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"zod": "^4.0.2",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user