d0825c5ec0
对仅含静态类名或单一三元表达式的 className 改用普通字符串,保留有条件合并或 prop 覆盖场景下的 cn() 用法。 Co-authored-by: Cursor <cursoragent@cursor.com>
81 lines
2.1 KiB
TypeScript
81 lines
2.1 KiB
TypeScript
import { ArrowLeft, ExternalLink } from 'lucide-react';
|
|
import { Button } from '@/components/ui/button';
|
|
import SearchDropdown from './SearchDropdown';
|
|
import SearchInput from './SearchInput';
|
|
import TopBarActions from './TopBarActions';
|
|
import { useTopBar } from './useTopBar';
|
|
|
|
export default function TopBar() {
|
|
const {
|
|
searchQuery,
|
|
searchResults,
|
|
recentFeatures,
|
|
selectedIndex,
|
|
isDashboard,
|
|
ThemeIcon,
|
|
themeTitle,
|
|
showDropdown,
|
|
containerRef,
|
|
inputRef,
|
|
handleSearchQueryChange,
|
|
handleSearchFocus,
|
|
handleSelectFeature,
|
|
handleKeyDown,
|
|
cycleThemeMode,
|
|
handleOpenInTab,
|
|
goHome,
|
|
clearSearch,
|
|
} = useTopBar();
|
|
|
|
const actions = [
|
|
{ id: 'theme', icon: ThemeIcon, title: themeTitle, onClick: cycleThemeMode },
|
|
{
|
|
id: 'open-in-tab',
|
|
icon: ExternalLink,
|
|
title: '在标签页打开',
|
|
onClick: () => void handleOpenInTab(),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<header className="relative z-50 flex h-14 items-center justify-between border-b border-border bg-background px-4">
|
|
<div className="flex w-10 items-center justify-start">
|
|
{!isDashboard && (
|
|
<Button
|
|
type="button"
|
|
variant="outline"
|
|
size="icon"
|
|
onClick={goHome}
|
|
aria-label="返回首页"
|
|
className="h-8 w-8 shadow-sm text-muted-foreground"
|
|
>
|
|
<ArrowLeft className="h-4 w-4" />
|
|
</Button>
|
|
)}
|
|
</div>
|
|
|
|
<div ref={containerRef} className="relative mx-4 max-w-md flex-1">
|
|
<SearchInput
|
|
inputRef={inputRef}
|
|
searchQuery={searchQuery}
|
|
onSearchQueryChange={handleSearchQueryChange}
|
|
onFocus={handleSearchFocus}
|
|
onKeyDown={handleKeyDown}
|
|
onClear={clearSearch}
|
|
/>
|
|
{showDropdown && (
|
|
<SearchDropdown
|
|
searchQuery={searchQuery}
|
|
searchResults={searchResults}
|
|
recentFeatures={recentFeatures}
|
|
selectedIndex={selectedIndex}
|
|
onSelect={handleSelectFeature}
|
|
/>
|
|
)}
|
|
</div>
|
|
|
|
<TopBarActions actions={actions} />
|
|
</header>
|
|
);
|
|
}
|