Files
triggerdotdev--trigger.dev/apps/webapp/app/components/primitives/PageHeader.tsx
T
2026-07-13 13:32:57 +08:00

81 lines
2.5 KiB
TypeScript

import { Link, useNavigation } from "@remix-run/react";
import { type ReactNode } from "react";
import { QuestionMarkIcon } from "~/assets/icons/QuestionMarkIcon";
import { OrgBanner } from "../billing/OrgBanner";
import { BreadcrumbIcon } from "./BreadcrumbIcon";
import { Header2 } from "./Headers";
import { LoadingBarDivider } from "./LoadingBarDivider";
import { SimpleTooltip } from "./Tooltip";
import { DashboardAgentLauncher } from "../dashboard-agent/dashboardAgentLauncher";
type WithChildren = {
children: React.ReactNode;
className?: string;
};
export function NavBar({ children }: WithChildren) {
const navigation = useNavigation();
const isLoading = navigation.state === "loading" || navigation.state === "submitting";
return (
<div>
<div className="grid h-10 w-full grid-rows-[auto_1px] bg-background-bright">
<div className="flex w-full items-center gap-2 pl-3 pr-2">
<div className="flex flex-1 items-center justify-between">{children}</div>
<DashboardAgentLauncher />
</div>
<LoadingBarDivider isLoading={isLoading} />
</div>
<OrgBanner />
</div>
);
}
type PageTitleProps = {
title: ReactNode;
backButton?: {
to: string;
text: string;
};
/**
* Renders to the right of the title.
* - Pass a string → a question-mark icon with the string as its hover tooltip.
* - Pass a ReactNode → rendered verbatim, for custom adornments.
*/
accessory?: ReactNode;
};
export function PageTitle({ title, backButton, accessory }: PageTitleProps) {
return (
<div className="flex items-center gap-1">
{backButton && (
<div className="group -ml-1.5 flex items-center gap-0">
<Link
to={backButton.to}
className="rounded px-1.5 py-1 text-xs text-text-dimmed transition focus-custom group-hover:bg-background-raised group-hover:text-text-bright"
>
{backButton.text}
</Link>
<BreadcrumbIcon className="h-5" />
</div>
)}
<Header2 className="flex items-center gap-1">{title}</Header2>
{accessory !== undefined &&
(typeof accessory === "string" ? (
<SimpleTooltip
button={<QuestionMarkIcon className="size-4 text-text-dimmed" />}
content={accessory}
className="max-w-xs"
disableHoverableContent
/>
) : (
accessory
))}
</div>
);
}
export function PageAccessories({ children }: WithChildren) {
return <div className="flex items-center gap-2">{children}</div>;
}