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
@@ -97,6 +97,8 @@ import { type OrganizeSource, OrganizeWizard } from "~/components/organize-wizar
|
||||
import { Button } from "~/components/ui/button.tsx";
|
||||
import { Input } from "~/components/ui/input.tsx";
|
||||
import { Pagination } from "~/components/ui/pagination.tsx";
|
||||
import { SegmentedControl } from "~/components/ui/segmented.tsx";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select.tsx";
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle } from "~/components/ui/sheet.tsx";
|
||||
import { relTime } from "~/components/workbench/release-fields.ts";
|
||||
import { useSse } from "~/lib/sse.ts";
|
||||
@@ -797,23 +799,14 @@ export default function FilesPage() {
|
||||
|
||||
// ── 工具栏 ──
|
||||
const chips = (
|
||||
<div className="flex gap-1 overflow-x-auto scroll-bleed">
|
||||
{FILTER_CHIPS.map((c) => (
|
||||
<button
|
||||
key={c.value}
|
||||
type="button"
|
||||
aria-pressed={filter === c.value}
|
||||
onClick={() => patch({ f: c.value || null })}
|
||||
className={cn(
|
||||
"shrink-0 rounded-full border px-2.5 py-1 text-meta whitespace-nowrap transition-colors duration-micro",
|
||||
filter === c.value
|
||||
? "pill-selected text-foreground"
|
||||
: "border-border text-muted-foreground hover:text-foreground",
|
||||
)}
|
||||
>
|
||||
{c.label}
|
||||
</button>
|
||||
))}
|
||||
<div className="min-w-0 overflow-x-auto scroll-bleed">
|
||||
<SegmentedControl
|
||||
label="筛选"
|
||||
size="xs"
|
||||
value={filter || "all"}
|
||||
onChange={(v) => patch({ f: v === "all" ? null : v })}
|
||||
options={FILTER_CHIPS.map((c) => ({ value: c.value || "all", label: c.label }))}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
const searchBox = (
|
||||
@@ -838,21 +831,21 @@ export default function FilesPage() {
|
||||
</div>
|
||||
);
|
||||
const sortControls = (
|
||||
<div className="flex items-center gap-1">
|
||||
<select
|
||||
aria-label="排序"
|
||||
value={sort}
|
||||
onChange={(e) => patch({ sort: e.target.value === "name" ? null : e.target.value })}
|
||||
className="field-glass h-8 rounded-xl px-2 text-caption"
|
||||
>
|
||||
{SORT_OPTIONS.map((o) => (
|
||||
<option key={o.value} value={o.value}>
|
||||
按{o.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="flex items-center gap-2">
|
||||
<Select value={sort} onValueChange={(v) => patch({ sort: v === "name" ? null : v })}>
|
||||
<SelectTrigger size="sm" aria-label="排序" className="min-w-28 text-caption">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent position="popper" align="end">
|
||||
{SORT_OPTIONS.map((o) => (
|
||||
<SelectItem key={o.value} value={o.value}>
|
||||
按{o.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Button
|
||||
variant="ghost"
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
aria-label={order === "asc" ? "升序,切换为降序" : "降序,切换为升序"}
|
||||
title={order === "asc" ? "升序" : "降序"}
|
||||
@@ -861,13 +854,12 @@ export default function FilesPage() {
|
||||
{order === "asc" ? <ArrowDownAZ /> : <ArrowUpAZ />}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
aria-pressed={hidden}
|
||||
aria-label={hidden ? "不显示隐藏文件" : "显示隐藏文件"}
|
||||
title={hidden ? "正在显示隐藏文件" : "显示隐藏文件"}
|
||||
onClick={() => patch({ hidden: hidden ? null : "1" })}
|
||||
className={cn(hidden && "bg-foreground/[0.08] text-foreground")}
|
||||
>
|
||||
{hidden ? <Eye /> : <EyeOff />}
|
||||
</Button>
|
||||
@@ -1007,7 +999,7 @@ export default function FilesPage() {
|
||||
<span className="flex-1" />
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
aria-label={searchOpen ? "收起搜索" : "搜索"}
|
||||
onClick={() => {
|
||||
@@ -1018,7 +1010,7 @@ export default function FilesPage() {
|
||||
{searchOpen ? <X /> : <Search />}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
aria-label="更多"
|
||||
onClick={(ev) => openMenuAt(ev.currentTarget, mobileMore())}
|
||||
@@ -1032,7 +1024,7 @@ export default function FilesPage() {
|
||||
<div className="space-y-2 border-b border-border px-3 py-2.5">
|
||||
<div className="flex min-w-0 items-center gap-1.5">
|
||||
<Button
|
||||
variant="ghost"
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
aria-label="上一级"
|
||||
title="上一级(Alt+↑)"
|
||||
@@ -1053,7 +1045,7 @@ export default function FilesPage() {
|
||||
<span className="flex-1" />
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
aria-label="刷新"
|
||||
title="刷新"
|
||||
@@ -1067,7 +1059,7 @@ export default function FilesPage() {
|
||||
<RotateCw className={cn(list.isFetching && !list.isFetchingNextPage && "animate-spin")} />
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
variant="outline"
|
||||
size="icon-sm"
|
||||
aria-label="快捷键"
|
||||
title="快捷键(?)"
|
||||
|
||||
Reference in new issue
Block a user