feat(ui): 优化首页切换为分段控件;精简 Banner 间距;标题在上切换在下

This commit is contained in:
Jason
2025-08-31 00:03:22 +08:00
parent 0cb89c8f67
commit c98a724935
2 changed files with 99 additions and 53 deletions

View File

@@ -5,67 +5,90 @@
} }
.app-header { .app-header {
background: #3498db; background: linear-gradient(180deg, #3498db 0%, #2d89c7 100%);
color: white; color: white;
padding: 0.75rem 2rem; padding: 0.35rem 2rem 0.45rem;
display: flex; display: grid;
justify-content: space-between; grid-template-columns: 1fr auto;
grid-template-rows: auto auto;
grid-template-areas:
"title actions"
"tabs actions";
align-items: center; align-items: center;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); row-gap: 0.45rem; /* 间隔增大一点,标题与开关分离 */
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
user-select: none; user-select: none;
min-height: 3rem;
position: relative;
} }
.app-tabs { .app-tabs {
position: absolute; grid-area: tabs;
left: 2rem;
top: 0;
display: flex;
height: 100%;
} }
.app-tab { /* Segmented control */
background: transparent; .segmented {
color: rgba(255, 255, 255, 0.7); --seg-bg: rgba(255, 255, 255, 0.16);
border: none; --seg-thumb: #ffffff;
padding: 0 1.5rem; --seg-color: rgba(255, 255, 255, 0.85);
cursor: pointer; --seg-active: #2d89c7;
font-size: 0.95rem;
font-weight: 500;
transition: all 0.2s;
position: relative; position: relative;
display: grid;
grid-template-columns: 1fr 1fr;
width: 280px;
background: var(--seg-bg);
border-radius: 999px;
padding: 4px;
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.15);
backdrop-filter: saturate(140%) blur(2px);
} }
.app-tab:hover { .segmented-thumb {
color: white;
background: rgba(255, 255, 255, 0.1);
}
.app-tab.active {
color: white;
background: rgba(255, 255, 255, 0.15);
}
.app-tab.active::after {
content: "";
position: absolute; position: absolute;
bottom: 0; top: 4px;
left: 0; left: 4px;
right: 0; width: calc(50% - 4px);
height: 3px; height: calc(100% - 8px);
background: white; background: var(--seg-thumb);
border-radius: 999px;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
transition: transform 220ms ease, width 220ms ease;
will-change: transform;
}
.segmented-item {
position: relative;
z-index: 1;
background: transparent;
border: none;
border-radius: 999px;
padding: 6px 16px; /* 更紧凑的高度 */
color: var(--seg-color);
font-size: 0.95rem;
font-weight: 600;
letter-spacing: 0.2px;
cursor: pointer;
transition: color 200ms ease;
}
.segmented-item.active {
color: var(--seg-active);
}
.segmented-item:focus-visible {
outline: 2px solid rgba(255, 255, 255, 0.8);
outline-offset: 2px;
} }
.app-header h1 { .app-header h1 {
font-size: 1.5rem; font-size: 1.5rem;
font-weight: 500; font-weight: 500;
margin: 0 auto; margin: 0;
grid-area: title;
} }
.header-actions { .header-actions {
display: flex; display: flex;
gap: 1rem; gap: 1rem;
grid-area: actions;
} }
.refresh-btn, .refresh-btn,

View File

@@ -180,21 +180,44 @@ function App() {
return ( return (
<div className="app"> <div className="app">
<header className="app-header"> <header className="app-header">
<div className="app-tabs">
<button
className={`app-tab ${activeApp === "claude" ? "active" : ""}`}
onClick={() => setActiveApp("claude")}
>
Claude Code
</button>
<button
className={`app-tab ${activeApp === "codex" ? "active" : ""}`}
onClick={() => setActiveApp("codex")}
>
Codex
</button>
</div>
<h1>{activeApp === "claude" ? "Claude Code" : "Codex"} </h1> <h1>{activeApp === "claude" ? "Claude Code" : "Codex"} </h1>
<div className="app-tabs">
<div
className="segmented"
role="tablist"
aria-label="选择应用"
>
<span
className="segmented-thumb"
style={{
transform:
activeApp === "claude" ? "translateX(0%)" : "translateX(100%)",
}}
/>
<button
type="button"
role="tab"
aria-selected={activeApp === "claude"}
className={`segmented-item ${
activeApp === "claude" ? "active" : ""
}`}
onClick={() => setActiveApp("claude")}
>
Claude Code
</button>
<button
type="button"
role="tab"
aria-selected={activeApp === "codex"}
className={`segmented-item ${
activeApp === "codex" ? "active" : ""
}`}
onClick={() => setActiveApp("codex")}
>
Codex
</button>
</div>
</div>
<div className="header-actions"> <div className="header-actions">
<button className="add-btn" onClick={() => setIsAddModalOpen(true)}> <button className="add-btn" onClick={() => setIsAddModalOpen(true)}>