mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
feat: add sidebar
This commit is contained in:
parent
7db2703b33
commit
e5d2815b41
41 changed files with 2469 additions and 1391 deletions
89
web/src/contexts/PageHeaderProvider.tsx
Normal file
89
web/src/contexts/PageHeaderProvider.tsx
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import { useLayoutEffect, useMemo, useState, type ReactNode } from "react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { PageHeaderContext } from "./page-header-context";
|
||||
import { resolvePageTitle } from "@/lib/resolve-page-title";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useI18n } from "@/i18n";
|
||||
|
||||
export function PageHeaderProvider({
|
||||
children,
|
||||
pluginTabs,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
pluginTabs: { path: string; label: string }[];
|
||||
}) {
|
||||
const { pathname } = useLocation();
|
||||
const { t } = useI18n();
|
||||
const [titleOverride, setTitleOverride] = useState<string | null>(null);
|
||||
const [afterTitle, setAfterTitle] = useState<ReactNode>(null);
|
||||
const [end, setEnd] = useState<ReactNode>(null);
|
||||
|
||||
// Clear any per-page title / toolbar slots when the path changes. Child routes
|
||||
// re-fill these on mount via usePageHeader.
|
||||
/* eslint-disable react-hooks/set-state-in-effect */
|
||||
useLayoutEffect(() => {
|
||||
setTitleOverride(null);
|
||||
setAfterTitle(null);
|
||||
setEnd(null);
|
||||
}, [pathname]);
|
||||
/* eslint-enable react-hooks/set-state-in-effect */
|
||||
|
||||
const defaultTitle = useMemo(
|
||||
() => resolvePageTitle(pathname, t, pluginTabs),
|
||||
[pathname, t, pluginTabs],
|
||||
);
|
||||
const displayTitle = titleOverride ?? defaultTitle;
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
setAfterTitle,
|
||||
setEnd,
|
||||
setTitle: setTitleOverride,
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<PageHeaderContext.Provider value={value}>
|
||||
<div className="flex min-h-0 w-full min-w-0 flex-1 flex-col overflow-hidden">
|
||||
<header
|
||||
className={cn(
|
||||
"z-1 box-border h-14 shrink-0 border-b border-current/20",
|
||||
"bg-background-base/40 backdrop-blur-sm",
|
||||
"overflow-hidden",
|
||||
)}
|
||||
role="banner"
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
"flex h-full w-full min-w-0 flex-1 flex-col justify-center gap-2",
|
||||
"px-3 py-2 sm:px-6",
|
||||
"min-h-14 sm:min-h-0 sm:flex-row sm:items-center sm:gap-3 sm:py-0",
|
||||
)}
|
||||
>
|
||||
<div className="flex min-w-0 flex-1 items-center gap-2 sm:gap-3">
|
||||
<h1
|
||||
className="font-expanded min-w-0 truncate text-sm font-bold tracking-[0.08em] text-midground"
|
||||
style={{ mixBlendMode: "plus-lighter" }}
|
||||
>
|
||||
{displayTitle}
|
||||
</h1>
|
||||
{afterTitle}
|
||||
</div>
|
||||
|
||||
{end ? (
|
||||
<div className="flex w-full min-w-0 justify-end sm:max-w-md sm:flex-1">
|
||||
{end}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</header>
|
||||
<main
|
||||
className="min-h-0 w-full min-w-0 flex-1 overflow-y-auto overflow-x-hidden"
|
||||
>
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
</PageHeaderContext.Provider>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue