feat(polaris): 完善首页背景与搜索入口视觉

使用本地背景和官方 Provider 图标,闭合状态仅展示当前图标。
调整冷蓝磨砂层次,并移除快捷卡片外部阴影以消除底部色带。
补充搜索 Provider 展示行为测试。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-07 22:25:30 +08:00
co-authored by Claude Opus 4.8
parent c3d2a40c1f
commit 178478190f
9 changed files with 132 additions and 80 deletions
@@ -72,6 +72,34 @@ describe("SearchBox", () => {
expect(input).toHaveFocus()
})
it("闭合态只显示当前图标,展开后显示 Provider 名称", async () => {
const user = userEvent.setup()
renderSearchBox()
const trigger = screen.getByRole("button", {
name: "选择搜索方式,当前为 Google",
})
expect(trigger.textContent).toBe("")
expect(trigger.querySelector("img")).toHaveAttribute(
"src",
"/icons/google.svg",
)
await user.click(trigger)
for (const [label, icon] of [
["Google", "google"],
["Bing", "bing"],
["GitHub", "github"],
["本地", "local"],
] as const) {
const item = screen.getByRole("menuitemradio", { name: label })
expect(item.querySelector("img")).toHaveAttribute(
"src",
`/icons/${icon}.svg`,
)
}
})
it("Google 模式回车只执行当前页外部导航", async () => {
const user = userEvent.setup()
const { onExternalNavigate } = renderSearchBox()
@@ -1,12 +1,6 @@
"use client"
import {
Database,
GitFork,
Globe2,
Search,
type LucideIcon,
} from "lucide-react"
import Image from "next/image"
import { Button } from "@/components/ui/button"
import {
@@ -26,11 +20,24 @@ const PROVIDER_LABELS: Record<SearchProvider, string> = {
local: "本地",
}
const PROVIDER_ICONS: Record<SearchProvider, LucideIcon> = {
google: Globe2,
bing: Search,
github: GitFork,
local: Database,
const PROVIDER_ICON_PATHS: Record<SearchProvider, string> = {
google: "/icons/google.svg",
bing: "/icons/bing.svg",
github: "/icons/github.svg",
local: "/icons/local.svg",
}
function ProviderIcon({ provider }: { provider: SearchProvider }) {
return (
<Image
className="search-provider-menu__icon"
src={PROVIDER_ICON_PATHS[provider]}
alt=""
width={24}
height={24}
aria-hidden="true"
/>
)
}
type SearchProviderMenuProps = {
@@ -44,8 +51,6 @@ export function SearchProviderMenu({
enabledProviders,
onProviderChange,
}: SearchProviderMenuProps) {
const CurrentIcon = PROVIDER_ICONS[provider]
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
@@ -55,8 +60,7 @@ export function SearchProviderMenu({
className="search-provider-menu__trigger"
aria-label={`选择搜索方式,当前为 ${PROVIDER_LABELS[provider]}`}
>
<CurrentIcon aria-hidden="true" />
<span>{PROVIDER_LABELS[provider]}</span>
<ProviderIcon provider={provider} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
@@ -67,13 +71,12 @@ export function SearchProviderMenu({
}}
>
{enabledProviders.map((enabledProvider) => {
const Icon = PROVIDER_ICONS[enabledProvider]
return (
<DropdownMenuRadioItem
key={enabledProvider}
value={enabledProvider}
>
<Icon aria-hidden="true" />
<ProviderIcon provider={enabledProvider} />
{PROVIDER_LABELS[enabledProvider]}
</DropdownMenuRadioItem>
)