style(ui): 组件圆角类对齐三档梯度(32/16/8)

配合 input.css 的 token 化,把散落在 RSX 组件里的孤悬圆角档位
统一到内容档 16px (rounded-2xl):

消除 24px (rounded-3xl, 4处无规范依据的中间档):
- ADMIN_CARD_CLASS / ADMIN_TABLE_CLASS (ui.rs)
- write.rs 编辑器容器 / write_skeleton.rs 编辑器骨架

消除 12px (rounded-xl, 10处):
- INPUT_CLASS (forms.rs) 与 write 页输入框统一到 16px
- write 页 3 处输入框 + 4 处错误提示框
- admin_layout 退出按钮
- system/admin_skeleton/posts_trash 卡片容器
- write_skeleton 骨架条(模拟输入框形状,跟随真实圆角)

改造后全站只剩 4 种圆角语义: 32px容器 / 16px内容 / 8px微元素 /
胶囊按钮,孤悬档位彻底清除。
This commit is contained in:
xfy 2026-07-13 16:21:10 +08:00
parent 248dcb761c
commit ee9d2ecd6e
8 changed files with 25 additions and 25 deletions

View File

@ -111,7 +111,7 @@ pub fn AdminLayout() -> Element {
div { class: "mt-auto pt-6 border-t border-[var(--color-paper-border)] flex items-center justify-between px-4",
ThemeToggle {}
button {
class: "text-sm font-medium px-4 py-2 rounded-xl bg-[var(--color-paper-theme)] border border-[var(--color-paper-border)] shadow-sm hover:shadow-md transition-all text-[var(--color-paper-secondary)] hover:text-red-500 cursor-pointer",
class: "text-sm font-medium px-4 py-2 rounded-2xl bg-[var(--color-paper-theme)] border border-[var(--color-paper-border)] shadow-sm hover:shadow-md transition-all text-[var(--color-paper-secondary)] hover:text-red-500 cursor-pointer",
onclick: move |_| {
spawn(async move {
let _ = logout().await;

View File

@ -17,7 +17,7 @@ pub fn AdminDashboardSkeleton() -> Element {
// 统计卡片骨架
div { class: "grid grid-cols-1 md:grid-cols-3 gap-6",
for _ in 0..3 {
div { class: "rounded-xl bg-paper-entry border border-paper-border p-6 text-center space-y-3",
div { class: "rounded-2xl bg-paper-entry border border-paper-border p-6 text-center space-y-3",
SkeletonBox { class: "h-9 w-16 mx-auto rounded" }
SkeletonBox { class: "h-4 w-20 mx-auto rounded" }
}

View File

@ -5,7 +5,7 @@
use dioxus::prelude::*;
/// 输入框基础 CSS 类统一文本框、邮箱框、URL 框等样式。
pub const INPUT_CLASS: &str = "w-full px-4 py-2 border border-paper-border rounded-lg bg-paper-entry text-paper-primary placeholder:text-paper-tertiary focus:outline-none focus:border-paper-accent focus:ring-1 focus:ring-paper-accent/30 transition-colors duration-200";
pub const INPUT_CLASS: &str = "w-full px-4 py-2 border border-paper-border rounded-2xl bg-paper-entry text-paper-primary placeholder:text-paper-tertiary focus:outline-none focus:border-paper-accent focus:ring-1 focus:ring-paper-accent/30 transition-colors duration-200";
/// 主按钮 CSS 类,用于表单提交等主操作按钮。
pub const BUTTON_PRIMARY_CLASS: &str = "w-full py-2.5 px-4 bg-paper-accent text-white font-medium rounded-full hover:brightness-110 active:scale-[0.98] transition-all duration-200 cursor-pointer";

View File

@ -15,11 +15,11 @@ use crate::router::Route;
// 样式常量
// ===========================================================================
/// Admin 卡片容器:大圆角,极简风,现代简约
pub const ADMIN_CARD_CLASS: &str = "bg-[var(--color-paper-entry)] rounded-3xl shadow-sm border border-transparent hover:border-[var(--color-paper-border)] transition-colors";
/// Admin 卡片容器:内容档圆角16px作为主面板内的内容卡片与外壳 32px 形成层次
pub const ADMIN_CARD_CLASS: &str = "bg-[var(--color-paper-entry)] rounded-2xl shadow-sm border border-transparent hover:border-[var(--color-paper-border)] transition-colors";
/// Admin 表格容器:大圆角,现代简约,与卡片一致。
pub const ADMIN_TABLE_CLASS: &str = "bg-[var(--color-paper-entry)] rounded-3xl shadow-sm border border-transparent hover:border-[var(--color-paper-border)] transition-colors overflow-hidden";
/// Admin 表格容器:内容档圆角16px,与卡片一致。
pub const ADMIN_TABLE_CLASS: &str = "bg-[var(--color-paper-entry)] rounded-2xl shadow-sm border border-transparent hover:border-[var(--color-paper-border)] transition-colors overflow-hidden";
/// Admin 表格行 hover 态:底部分割线 + 悬停背景。
pub const ADMIN_ROW_HOVER: &str =

View File

@ -25,7 +25,7 @@ pub fn WriteSkeleton() -> Element {
// 编辑器区域:flex-1 撑满左栏剩余高度
div { class: "flex-1 min-h-[400px] flex flex-col my-4",
div { class: "flex-1 min-h-0 w-full border border-[var(--color-paper-border)] rounded-3xl overflow-hidden bg-[var(--color-paper-entry)] shadow-sm p-4",
div { class: "flex-1 min-h-0 w-full border border-[var(--color-paper-border)] rounded-2xl overflow-hidden bg-[var(--color-paper-entry)] shadow-sm p-4",
// 工具栏
div { class: "flex gap-2 pb-3 border-b border-[var(--color-paper-border)]",
for _ in 0..8 {
@ -51,17 +51,17 @@ pub fn WriteSkeleton() -> Element {
// 链接节
div { class: "p-6 border-b border-[var(--color-paper-border)]",
SkeletonBox { class: "h-3 w-10 rounded mb-3" }
SkeletonBox { class: "h-8 w-full rounded-xl" }
SkeletonBox { class: "h-8 w-full rounded-2xl" }
}
// 标签节
div { class: "p-6 border-b border-[var(--color-paper-border)]",
SkeletonBox { class: "h-3 w-10 rounded mb-3" }
SkeletonBox { class: "h-8 w-full rounded-xl" }
SkeletonBox { class: "h-8 w-full rounded-2xl" }
}
// 摘要节
div { class: "p-6 border-b border-[var(--color-paper-border)]",
SkeletonBox { class: "h-3 w-10 rounded mb-3" }
SkeletonBox { class: "h-16 w-full rounded-xl" }
SkeletonBox { class: "h-16 w-full rounded-2xl" }
}
// 封面图节
div { class: "p-6",

View File

@ -367,7 +367,7 @@ fn AutoPurgeSettings(settings: Signal<TrashSettings>) -> Element {
};
rsx! {
div { class: "rounded-xl border border-paper-border overflow-hidden bg-paper-entry",
div { class: "rounded-2xl border border-paper-border overflow-hidden bg-paper-entry",
// 顶部可点击摘要条:状态指示灯 + 标题 + 展开箭头
button {
class: "w-full flex items-center gap-3 px-5 py-4 text-left cursor-pointer hover:bg-paper-theme focus:outline-none focus-visible:ring-2 focus-visible:ring-paper-accent/40",

View File

@ -421,14 +421,14 @@ fn DbStatusTab() -> Element {
// 概览卡片骨架
div { class: "grid grid-cols-2 md:grid-cols-4 gap-4",
for _ in 0..4 {
div { class: "rounded-xl bg-paper-entry border border-paper-border p-4 space-y-2",
div { class: "rounded-2xl bg-paper-entry border border-paper-border p-4 space-y-2",
SkeletonBox { class: "h-3 w-16 rounded" }
SkeletonBox { class: "h-6 w-24 rounded" }
}
}
}
// 表清单骨架
div { class: "rounded-xl bg-paper-entry border border-paper-border overflow-hidden",
div { class: "rounded-2xl bg-paper-entry border border-paper-border overflow-hidden",
div { class: "px-4 py-3 border-b border-paper-border",
SkeletonBox { class: "h-4 w-40 rounded" }
}
@ -704,7 +704,7 @@ fn ServerStatusTab() -> Element {
// 应用内指标卡片骨架
div { class: "grid grid-cols-2 md:grid-cols-4 gap-4",
for _ in 0..4 {
div { class: "rounded-xl bg-paper-entry border border-paper-border p-4 space-y-2",
div { class: "rounded-2xl bg-paper-entry border border-paper-border p-4 space-y-2",
SkeletonBox { class: "h-3 w-16 rounded" }
SkeletonBox { class: "h-6 w-24 rounded" }
}
@ -713,14 +713,14 @@ fn ServerStatusTab() -> Element {
// 主机层指标卡片骨架
div { class: "grid grid-cols-2 md:grid-cols-4 gap-4",
for _ in 0..4 {
div { class: "rounded-xl bg-paper-entry border border-paper-border p-4 space-y-2",
div { class: "rounded-2xl bg-paper-entry border border-paper-border p-4 space-y-2",
SkeletonBox { class: "h-3 w-16 rounded" }
SkeletonBox { class: "h-6 w-24 rounded" }
}
}
}
// 缓存命中率表骨架
div { class: "rounded-xl bg-paper-entry border border-paper-border overflow-hidden",
div { class: "rounded-2xl bg-paper-entry border border-paper-border overflow-hidden",
div { class: "px-4 py-3 border-b border-paper-border",
SkeletonBox { class: "h-4 w-24 rounded" }
}

View File

@ -432,13 +432,13 @@ fn write_editor(post_id: Option<i32>) -> Element {
// 错误和成功提示
if let Some(err) = load_error() {
div { class: "flex-shrink-0 px-4 py-2 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-xl text-sm border border-red-100 dark:border-red-900/30 mb-2",
div { class: "flex-shrink-0 px-4 py-2 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-2xl text-sm border border-red-100 dark:border-red-900/30 mb-2",
"{err}"
}
}
if let Some(err) = error() {
div { class: "flex-shrink-0 px-4 py-2 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-xl text-sm border border-red-100 dark:border-red-900/30 mb-2",
div { class: "flex-shrink-0 px-4 py-2 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-2xl text-sm border border-red-100 dark:border-red-900/30 mb-2",
"{err}"
}
}
@ -447,7 +447,7 @@ fn write_editor(post_id: Option<i32>) -> Element {
for err in upload_errors().clone() {
div {
key: "{err.id}",
class: "flex-shrink-0 flex items-center justify-between gap-3 px-4 py-2 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-xl text-sm border border-red-100 dark:border-red-900/30 mb-2",
class: "flex-shrink-0 flex items-center justify-between gap-3 px-4 py-2 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-2xl text-sm border border-red-100 dark:border-red-900/30 mb-2",
span { "图片上传失败: {err.file_name} — {err.message}" }
button {
class: "{BTN_CLOSE_ICON}",
@ -475,7 +475,7 @@ fn write_editor(post_id: Option<i32>) -> Element {
// 容器变高编辑器自动跟着变高。min-h-[400px] 保证窗口过矮时仍可用。
div { class: "flex-1 min-h-[400px] flex flex-col my-4",
div {
class: "relative group flex-1 min-h-0 w-full border border-[var(--color-paper-border)] rounded-3xl overflow-hidden bg-[var(--color-paper-entry)] shadow-sm",
class: "relative group flex-1 min-h-0 w-full border border-[var(--color-paper-border)] rounded-2xl overflow-hidden bg-[var(--color-paper-entry)] shadow-sm",
id: "tiptap-editor",
img {
src: "/images/xiantiaoxiaogou_input_bg.webp",
@ -493,7 +493,7 @@ fn write_editor(post_id: Option<i32>) -> Element {
div { class: "p-6 border-b border-[var(--color-paper-border)]",
label { class: "block text-xs font-semibold uppercase tracking-wide text-[var(--color-paper-tertiary)] mb-3", "链接" }
input {
class: "w-full text-sm bg-[var(--color-paper-entry)] text-[var(--color-paper-primary)] placeholder-[var(--color-paper-tertiary)] focus:outline-none border border-[var(--color-paper-border)] focus:border-[var(--color-paper-primary)] rounded-xl px-3 py-2 transition-all",
class: "w-full text-sm bg-[var(--color-paper-entry)] text-[var(--color-paper-primary)] placeholder-[var(--color-paper-tertiary)] focus:outline-none border border-[var(--color-paper-border)] focus:border-[var(--color-paper-primary)] rounded-2xl px-3 py-2 transition-all",
placeholder: "自动生成",
value: "{slug}",
oninput: move |evt| slug.set(evt.value()),
@ -503,7 +503,7 @@ fn write_editor(post_id: Option<i32>) -> Element {
div { class: "p-6 border-b border-[var(--color-paper-border)]",
label { class: "block text-xs font-semibold uppercase tracking-wide text-[var(--color-paper-tertiary)] mb-3", "标签" }
input {
class: "w-full text-sm bg-[var(--color-paper-entry)] text-[var(--color-paper-primary)] placeholder-[var(--color-paper-tertiary)] focus:outline-none border border-[var(--color-paper-border)] focus:border-[var(--color-paper-primary)] rounded-xl px-3 py-2 transition-all",
class: "w-full text-sm bg-[var(--color-paper-entry)] text-[var(--color-paper-primary)] placeholder-[var(--color-paper-tertiary)] focus:outline-none border border-[var(--color-paper-border)] focus:border-[var(--color-paper-primary)] rounded-2xl px-3 py-2 transition-all",
placeholder: "逗号分隔...",
value: "{tags}",
oninput: move |evt| tags.set(evt.value()),
@ -513,7 +513,7 @@ fn write_editor(post_id: Option<i32>) -> Element {
div { class: "p-6 border-b border-[var(--color-paper-border)]",
label { class: "block text-xs font-semibold uppercase tracking-wide text-[var(--color-paper-tertiary)] mb-3", "摘要" }
textarea {
class: "w-full text-sm bg-[var(--color-paper-entry)] text-[var(--color-paper-primary)] placeholder-[var(--color-paper-tertiary)] focus:outline-none border border-[var(--color-paper-border)] focus:border-[var(--color-paper-primary)] rounded-xl px-3 py-2 transition-all resize-none leading-relaxed",
class: "w-full text-sm bg-[var(--color-paper-entry)] text-[var(--color-paper-primary)] placeholder-[var(--color-paper-tertiary)] focus:outline-none border border-[var(--color-paper-border)] focus:border-[var(--color-paper-primary)] rounded-2xl px-3 py-2 transition-all resize-none leading-relaxed",
placeholder: "选填...",
rows: "3",
value: "{summary}",
@ -842,7 +842,7 @@ fn CoverUploader(cover_image: Signal<String>, cover_uploading: Signal<bool>) ->
// 封面上传失败提示:复用页面红色条风格。
if let Some(err) = cover_error() {
div { class: "flex items-center justify-between gap-3 px-4 py-2 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-xl text-sm border border-red-100 dark:border-red-900/30 mt-2",
div { class: "flex items-center justify-between gap-3 px-4 py-2 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-2xl text-sm border border-red-100 dark:border-red-900/30 mt-2",
span { "封面图: {err}" }
button {
class: "{BTN_CLOSE_ICON}",