From 6ed12ff1cb201473b7f88734a8b2159039bc1cc1 Mon Sep 17 00:00:00 2001 From: xfy Date: Thu, 4 Jun 2026 15:43:40 +0800 Subject: [PATCH] refactor: fix skeleton atoms - remove unused components, use &str, migrate all skeletons --- src/components/skeletons/archive_skeleton.rs | 10 ++--- src/components/skeletons/atoms.rs | 24 +---------- src/components/skeletons/home_skeleton.rs | 5 ++- .../skeletons/post_card_skeleton.rs | 14 ++++--- .../skeletons/post_detail_skeleton.rs | 40 +++++++++---------- src/components/skeletons/tags_skeleton.rs | 7 ++-- src/components/write_skeleton.rs | 28 ++++++------- 7 files changed, 56 insertions(+), 72 deletions(-) diff --git a/src/components/skeletons/archive_skeleton.rs b/src/components/skeletons/archive_skeleton.rs index 7f20862..2b84d94 100644 --- a/src/components/skeletons/archive_skeleton.rs +++ b/src/components/skeletons/archive_skeleton.rs @@ -10,29 +10,29 @@ pub fn ArchiveSkeleton() -> Element { div { // 统计行占位 div { class: "mt-2 mb-6", - SkeletonBox { class: "h-5 w-32".to_string() } + SkeletonBox { class: "h-5 w-32 rounded" } } // 年份分组占位 for _ in 0..2 { div { class: "archive-year mt-10", // 年份标题 (h2 text-2xl) - SkeletonBox { class: "h-8 w-24 mb-4".to_string() } + SkeletonBox { class: "h-8 w-24 rounded mb-4" } // 月份分组 for _ in 0..2 { div { class: "archive-month flex flex-col md:flex-row md:items-start py-2.5 border-b border-gray-100 dark:border-[#333]/50", // 月份标题 (h3 text-lg, md:w-[200px]) - SkeletonBox { class: "h-6 w-32 md:w-[200px] shrink-0 mb-2 md:mb-0 md:py-1.5".to_string() } + SkeletonBox { class: "h-6 w-32 md:w-[200px] shrink-0 rounded mb-2 md:mb-0 md:py-1.5" } // 文章条目列表 div { class: "flex-1 space-y-3", for _ in 0..3 { div { class: "archive-entry py-1.5 my-2.5", // 文章标题 - SkeletonBox { class: "h-4 w-3/4 mb-1".to_string() } + SkeletonBox { class: "h-4 w-3/4 rounded mb-1" } // 日期 - SkeletonBox { class: "h-3 w-20".to_string() } + SkeletonBox { class: "h-3 w-20 rounded" } } } } diff --git a/src/components/skeletons/atoms.rs b/src/components/skeletons/atoms.rs index ae3a88d..b262159 100644 --- a/src/components/skeletons/atoms.rs +++ b/src/components/skeletons/atoms.rs @@ -1,30 +1,10 @@ use dioxus::prelude::*; #[component] -pub fn SkeletonLine(width: String, height: String) -> Element { +pub fn SkeletonBox(class: &'static str) -> Element { rsx! { div { - class: "bg-gray-200 dark:bg-[#2a2a2a] rounded animate-pulse", - style: "width: {width}; height: {height};", - } - } -} - -#[component] -pub fn SkeletonBox(class: String) -> Element { - rsx! { - div { - class: "bg-gray-200 dark:bg-[#2a2a2a] rounded animate-pulse {class}", - } - } -} - -#[component] -pub fn SkeletonCard() -> Element { - rsx! { - div { class: "rounded-xl bg-white dark:bg-[#2e2e33] border border-gray-200 dark:border-[#333] p-6 text-center space-y-3", - SkeletonLine { width: "64px".to_string(), height: "36px".to_string() } - SkeletonLine { width: "80px".to_string(), height: "16px".to_string() } + class: "bg-gray-200 dark:bg-[#2a2a2a] animate-pulse {class}", } } } diff --git a/src/components/skeletons/home_skeleton.rs b/src/components/skeletons/home_skeleton.rs index fc84e5b..c0f6f8f 100644 --- a/src/components/skeletons/home_skeleton.rs +++ b/src/components/skeletons/home_skeleton.rs @@ -1,5 +1,6 @@ use dioxus::prelude::*; +use crate::components::skeletons::atoms::SkeletonBox; use crate::components::skeletons::post_card_skeleton::PostCardSkeleton; /// 首页骨架屏 - 模拟文章卡片列表 + 分页区域 @@ -14,8 +15,8 @@ pub fn HomeSkeleton() -> Element { } // 分页按钮占位 div { class: "flex mt-10 mb-6 justify-between", - div { class: "h-9 w-24 bg-gray-200 dark:bg-[#2a2a2a] rounded-full" } - div { class: "h-9 w-24 bg-gray-200 dark:bg-[#2a2a2a] rounded-full" } + SkeletonBox { class: "h-9 w-24 rounded-full" } + SkeletonBox { class: "h-9 w-24 rounded-full" } } } } diff --git a/src/components/skeletons/post_card_skeleton.rs b/src/components/skeletons/post_card_skeleton.rs index a62c516..9bba741 100644 --- a/src/components/skeletons/post_card_skeleton.rs +++ b/src/components/skeletons/post_card_skeleton.rs @@ -1,5 +1,7 @@ use dioxus::prelude::*; +use crate::components::skeletons::atoms::SkeletonBox; + /// 文章卡片骨架屏 - 模拟 PostCard 的视觉结构 /// 包含:标题行(24px bold) + 摘要2行 + 元信息行(日期+标签) #[component] @@ -8,16 +10,16 @@ pub fn PostCardSkeleton() -> Element { article { class: "mb-6 p-6 bg-white dark:bg-[#2e2e33] rounded-lg border border-gray-200 dark:border-[#333]", // 标题占位 (模拟 h2 text-2xl font-bold) - div { class: "h-7 w-3/4 bg-gray-200 dark:bg-[#2a2a2a] rounded mb-3" } + SkeletonBox { class: "h-7 w-3/4 rounded mb-3" } // 摘要第一行 - div { class: "h-4 w-full bg-gray-200 dark:bg-[#2a2a2a] rounded mb-2" } + SkeletonBox { class: "h-4 w-full rounded mb-2" } // 摘要第二行 - div { class: "h-4 w-5/6 bg-gray-200 dark:bg-[#2a2a2a] rounded mb-3" } + SkeletonBox { class: "h-4 w-5/6 rounded mb-3" } // 元信息行 (日期 + 标签) div { class: "flex items-center gap-3 mt-3", - div { class: "h-3.5 w-20 bg-gray-200 dark:bg-[#2a2a2a] rounded" } - div { class: "h-3.5 w-1 bg-gray-200 dark:bg-[#2a2a2a] rounded" } - div { class: "h-3.5 w-16 bg-gray-200 dark:bg-[#2a2a2a] rounded" } + SkeletonBox { class: "h-3.5 w-20 rounded" } + SkeletonBox { class: "h-3.5 w-1 rounded" } + SkeletonBox { class: "h-3.5 w-16 rounded" } } } } diff --git a/src/components/skeletons/post_detail_skeleton.rs b/src/components/skeletons/post_detail_skeleton.rs index b0339ea..e57adca 100644 --- a/src/components/skeletons/post_detail_skeleton.rs +++ b/src/components/skeletons/post_detail_skeleton.rs @@ -8,46 +8,46 @@ pub fn PostDetailSkeleton() -> Element { rsx! { article { class: "post-single", // 面包屑占位 - SkeletonBox { class: "h-4 w-48 mb-6".to_string() } + SkeletonBox { class: "h-4 w-48 rounded mb-6" } // 标题占位 (模拟 h1) - SkeletonBox { class: "h-10 w-4/5 mb-4".to_string() } + SkeletonBox { class: "h-10 w-4/5 rounded mb-4" } // 摘要占位 - SkeletonBox { class: "h-5 w-2/3 mb-4".to_string() } + SkeletonBox { class: "h-5 w-2/3 rounded mb-4" } // 元信息行 (作者 · 日期 · 阅读时间) div { class: "flex items-center gap-2 mb-8", - SkeletonBox { class: "h-4 w-16".to_string() } - SkeletonBox { class: "h-4 w-1".to_string() } - SkeletonBox { class: "h-4 w-24".to_string() } - SkeletonBox { class: "h-4 w-1".to_string() } - SkeletonBox { class: "h-4 w-20".to_string() } + SkeletonBox { class: "h-4 w-16 rounded" } + SkeletonBox { class: "h-4 w-1 rounded" } + SkeletonBox { class: "h-4 w-24 rounded" } + SkeletonBox { class: "h-4 w-1 rounded" } + SkeletonBox { class: "h-4 w-20 rounded" } } // 封面图占位 (模拟 PostCover 16:9 比例) - SkeletonBox { class: "w-full aspect-video rounded-lg mb-8".to_string() } + SkeletonBox { class: "w-full aspect-video rounded-lg mb-8" } // 正文段落占位 (模拟多段 PostContent) div { class: "space-y-4 mb-8", - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-5/6".to_string() } - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-3/4".to_string() } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-5/6 rounded" } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-3/4 rounded" } // 空行模拟段落间距 div { class: "h-2" } - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-2/3".to_string() } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-2/3 rounded" } } // PostFooter 占位 div { class: "border-t border-gray-200 dark:border-[#333] pt-6 mt-8", div { class: "flex items-center justify-between", - SkeletonBox { class: "h-4 w-32".to_string() } - SkeletonBox { class: "h-4 w-24".to_string() } + SkeletonBox { class: "h-4 w-32 rounded" } + SkeletonBox { class: "h-4 w-24 rounded" } } } } diff --git a/src/components/skeletons/tags_skeleton.rs b/src/components/skeletons/tags_skeleton.rs index d560477..907b02d 100644 --- a/src/components/skeletons/tags_skeleton.rs +++ b/src/components/skeletons/tags_skeleton.rs @@ -1,5 +1,6 @@ use dioxus::prelude::*; +use crate::components::skeletons::atoms::SkeletonBox; use crate::components::skeletons::post_card_skeleton::PostCardSkeleton; /// 标签列表页骨架屏 @@ -10,7 +11,7 @@ pub fn TagsSkeleton() -> Element { div { // 统计行占位 div { class: "mt-2 mb-6", - div { class: "h-5 w-48 bg-gray-200 dark:bg-[#2a2a2a] rounded" } + SkeletonBox { class: "h-5 w-48 rounded" } } // 标签云占位 (flex wrap gap-4) @@ -18,7 +19,7 @@ pub fn TagsSkeleton() -> Element { // 生成 24 个不同宽度的标签 pill for i in 0..24 { div { - class: "h-8 bg-gray-200 dark:bg-[#2a2a2a] rounded-lg", + class: "h-8 bg-gray-200 dark:bg-[#2a2a2a] rounded-lg animate-pulse", // 不同宽度模拟标签名长短 style: match i % 6 { 0 => "width: 60px;", @@ -42,7 +43,7 @@ pub fn TagDetailSkeleton() -> Element { div { // 统计行占位 div { class: "mt-2 mb-6", - div { class: "h-5 w-32 bg-gray-200 dark:bg-[#2a2a2a] rounded" } + SkeletonBox { class: "h-5 w-32 rounded" } } // 文章卡片列表 diff --git a/src/components/write_skeleton.rs b/src/components/write_skeleton.rs index 4026f2c..38de377 100644 --- a/src/components/write_skeleton.rs +++ b/src/components/write_skeleton.rs @@ -6,7 +6,7 @@ pub fn WriteSkeleton() -> Element { rsx! { div { class: "space-y-4", // 标题输入骨架 - SkeletonBox { class: "w-full h-[52px] mb-4".to_string() } + SkeletonBox { class: "w-full h-[52px] mb-4 rounded" } // 编辑器区域骨架 div { @@ -14,28 +14,28 @@ pub fn WriteSkeleton() -> Element { // 工具栏骨架 div { class: "flex gap-2 pb-4 border-b border-gray-100 dark:border-[#333]", for _ in 0..8 { - SkeletonBox { class: "w-8 h-8".to_string() } + SkeletonBox { class: "w-8 h-8 rounded" } } } // 内容行骨架 div { class: "space-y-3 pt-2", - SkeletonBox { class: "h-4 w-[90%]".to_string() } - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-[85%]".to_string() } - SkeletonBox { class: "h-4 w-[95%]".to_string() } - SkeletonBox { class: "h-4 w-[60%]".to_string() } - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-[75%]".to_string() } - SkeletonBox { class: "h-4 w-[80%]".to_string() } + SkeletonBox { class: "h-4 w-[90%] rounded" } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-[85%] rounded" } + SkeletonBox { class: "h-4 w-[95%] rounded" } + SkeletonBox { class: "h-4 w-[60%] rounded" } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-[75%] rounded" } + SkeletonBox { class: "h-4 w-[80%] rounded" } div { class: "h-4" } - SkeletonBox { class: "h-4 w-[70%]".to_string() } - SkeletonBox { class: "h-4 w-full".to_string() } - SkeletonBox { class: "h-4 w-[90%]".to_string() } + SkeletonBox { class: "h-4 w-[70%] rounded" } + SkeletonBox { class: "h-4 w-full rounded" } + SkeletonBox { class: "h-4 w-[90%] rounded" } } } // 保存按钮骨架 - SkeletonBox { class: "mt-4 h-10 w-28 rounded-full".to_string() } + SkeletonBox { class: "mt-4 h-10 w-28 rounded-full" } } } }