Files
codeg/src/components/layout/app-title-bar.tsx
2026-04-07 15:47:16 +08:00

87 lines
2.1 KiB
TypeScript

"use client"
import type { ReactNode } from "react"
import { usePlatform } from "@/hooks/use-platform"
import { useIsMobile } from "@/hooks/use-mobile"
import { cn } from "@/lib/utils"
import { WindowControls } from "./window-controls"
interface AppTitleBarProps {
left?: ReactNode
center?: ReactNode
right?: ReactNode
className?: string
rowClassName?: string
centerInteractive?: boolean
showWindowControls?: boolean
}
export function AppTitleBar({
left,
center,
right,
className,
rowClassName,
centerInteractive = false,
showWindowControls = true,
}: AppTitleBarProps) {
const { isMac, isWindows } = usePlatform()
const isMobile = useIsMobile()
const isDesktopRuntime =
typeof window !== "undefined" && "__TAURI_INTERNALS__" in window
const hasDesktopWindowChrome = showWindowControls && isDesktopRuntime
const rowPadding = cn(
"px-3",
isMac && hasDesktopWindowChrome && "pl-[92px]",
isWindows && hasDesktopWindowChrome && "pr-[138px]"
)
return (
<div
className={cn(
"relative shrink-0 border-b bg-muted/70 select-none",
isMobile ? "h-11" : "h-8",
className
)}
>
<div data-tauri-drag-region className="absolute inset-0" />
<div
data-tauri-drag-region
className={cn(
"relative z-10 flex h-full items-center",
rowPadding,
rowClassName
)}
>
<div className="min-w-0 flex-1">{left}</div>
{right ? (
<div
className={cn(
"ml-auto shrink-0",
isWindows && hasDesktopWindowChrome && "mr-4"
)}
>
{right}
</div>
) : null}
</div>
{center ? (
<div className="pointer-events-none absolute inset-0 z-20 flex items-center justify-center">
<div className={cn(centerInteractive && "pointer-events-auto")}>
{center}
</div>
</div>
) : null}
{hasDesktopWindowChrome && isWindows ? (
<div className="absolute right-0 top-0 z-30">
<WindowControls />
</div>
) : null}
</div>
)
}