From ff7d9e1e46ad1afc4389fdb9cb5d795f9169ea53 Mon Sep 17 00:00:00 2001 From: xfy Date: Tue, 30 Jun 2026 14:16:36 +0800 Subject: [PATCH] feat(ui): add Tabs component for page-level navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 与 FilterTabs(列表筛选 + 滑动动画)并列,职责区分: - FilterTabs:同质数据过滤(全部/待审/已通过) - Tabs:切换到结构不同的面板(数据库/服务器/SQL 控制台) 选中态用按钮自身 border-b-2 下划线(无动画)。 API 与 FilterTabs 对齐(String value + EventHandler),便于调用方迁移。 --- src/components/ui.rs | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/components/ui.rs b/src/components/ui.rs index b43ca5d..fd60bde 100644 --- a/src/components/ui.rs +++ b/src/components/ui.rs @@ -274,3 +274,48 @@ pub fn FilterTabs( } } } + +/// 页面级导航 Tab 组件。 +/// +/// 与 [`FilterTabs`] 的区别: +/// - [`FilterTabs`]:**列表筛选**语义,带平滑滑动底部指示条动画(靠 WASM 端测量 +/// `offsetLeft/offsetWidth`)。适合「全部 / 待审核 / 已通过」这类同质数据过滤。 +/// - `Tabs`:**页面导航**语义,选中态用按钮自身 `border-b-2` 下划线(无动画)。 +/// 适合「数据库状态 / 服务器状态 / SQL 控制台」这类切换到结构完全不同的面板。 +/// +/// 因 Dioxus 0.7 `#[component]` 宏不支持泛型类型参数,value 用 `String`(与 +/// `FilterTabs` 一致);调用方负责枚举 ↔ String 的桥接(见 `SystemTab::as_str`)。 +/// +/// Props: +/// - `items`:`(value, label)` 列表,`value` 是稳定字符串 key,`label` 是展示文案 +/// - `active_value`:当前选中项的 value +/// - `on_change`:切换时回调,传入新选中项的 value +// Task 3 起由 /admin/system 页面消费;在此之前无调用方,加 allow 抑制 dead_code(参考 src/api/auth.rs:427)。 +#[allow(dead_code)] +#[component] +pub fn Tabs( + items: Vec<(&'static str, &'static str)>, + active_value: String, + on_change: EventHandler, +) -> Element { + rsx! { + div { class: "flex flex-wrap gap-1 border-b border-paper-border", + for (value, label) in items { + button { + key: "{value}", + class: "px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors", + class: if active_value == *value { + "border-paper-accent text-paper-accent" + } else { + "border-transparent text-paper-secondary hover:text-paper-primary" + }, + onclick: { + let v = value.to_string(); + move |_| on_change.call(v.clone()) + }, + {label} + } + } + } + } +}