fix(web): 控制台界面细节与 uhd_web 控件规范对齐
- 顶栏搜索移进右侧玻璃胶囊;输入框改淡玻璃(边线 0.46 → 0.16,悬停加深,聚焦 / 出错保留光晕) - 新增 SegmentedControl(滑动 seg-thumb),替换站点、下载、订阅、文件、智能体列表及对话框里的实心选中块;Tabs 改为同一枚滑块 - 开关型按钮统一 outline + aria-pressed 选中外观;页头 / 工具栏次操作描边、图标钮描边圆;文件排序改 Select;下载总速度加标签 - 分页一页放得下时只留总数、空列表不渲染、按容器宽度收起按钮 - 运行状态存储区重排;智能体列表页与会话页共用外壳路由,标题与左栏不再重挂载 - 站点卡片「⋯」不再单独换行;设置导航、状态计数、多选条件改玻璃选中态 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
8ff1817845
commit
c9b4ceb301
32 files changed
+753
-639
No files matched your search
@@ -12,7 +12,7 @@ import { SiteCard, SiteTable } from "~/components/sites/site-card.tsx";
|
||||
import { type SiteDialog, SiteDialogHost, useSiteChecks } from "~/components/sites/site-dialogs.tsx";
|
||||
import { needsAttention, type SortKey, sortSites } from "~/components/sites/site-fields.ts";
|
||||
import { Button } from "~/components/ui/button.tsx";
|
||||
import { cn } from "~/lib/utils.ts";
|
||||
import { SegmentedControl } from "~/components/ui/segmented.tsx";
|
||||
|
||||
// 获取 → 站点:站点、凭证、健康、账号数据、RSS 的唯一入口(docs/design/site-center.md §4);
|
||||
// 按类型分组显示:PT 站 / 公开 BT 站(旧的自定义 RSS 源有的话单列);?new=<类型> 直接打开添加。
|
||||
@@ -143,13 +143,13 @@ export default function SitesPage() {
|
||||
{all.length ? (
|
||||
<div className="mb-4 flex flex-wrap items-center justify-between gap-3">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Segmented
|
||||
<SegmentedControl
|
||||
label="筛选"
|
||||
value={filter}
|
||||
onChange={(v) => setParam("filter", v === "all" ? null : v)}
|
||||
options={FILTERS.map((f) => ({
|
||||
...f,
|
||||
label: f.value === "attention" && attention ? `${f.label} ${attention}` : f.label,
|
||||
count: f.value === "attention" && attention ? attention : undefined,
|
||||
}))}
|
||||
/>
|
||||
<FilterSelect
|
||||
@@ -160,13 +160,13 @@ export default function SitesPage() {
|
||||
options={SORTS.filter((x) => x.value !== "name")}
|
||||
/>
|
||||
</div>
|
||||
<Segmented
|
||||
<SegmentedControl
|
||||
label="视图"
|
||||
value={view}
|
||||
onChange={(v) => setView(v as View)}
|
||||
options={[
|
||||
{ value: "cards", label: "卡片", icon: <LayoutGrid className="h-3.5 w-3.5" /> },
|
||||
{ value: "list", label: "列表", icon: <List className="h-3.5 w-3.5" /> },
|
||||
{ value: "cards", label: "卡片", icon: <LayoutGrid /> },
|
||||
{ value: "list", label: "列表", icon: <List /> },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -224,39 +224,3 @@ export default function SitesPage() {
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function Segmented({
|
||||
label,
|
||||
value,
|
||||
onChange,
|
||||
options,
|
||||
}: {
|
||||
label: string;
|
||||
value: string;
|
||||
onChange: (v: string) => void;
|
||||
options: { value: string; label: string; icon?: React.ReactNode }[];
|
||||
}) {
|
||||
return (
|
||||
<div role="radiogroup" aria-label={label} className="inline-flex gap-0.5 rounded-xl border border-border p-0.5">
|
||||
{options.map((o) => (
|
||||
// biome-ignore lint/a11y/useSemanticElements: 分段按钮
|
||||
<button
|
||||
key={o.value}
|
||||
type="button"
|
||||
role="radio"
|
||||
aria-checked={value === o.value}
|
||||
onClick={() => onChange(o.value)}
|
||||
className={cn(
|
||||
"inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1 text-caption transition-colors",
|
||||
value === o.value
|
||||
? "bg-foreground text-background"
|
||||
: "text-muted-foreground hover:bg-accent hover:text-foreground",
|
||||
)}
|
||||
>
|
||||
{o.icon}
|
||||
{o.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user