هيكل التحميل (Skeleton)
يحجز هيكل التحميل (Skeleton) مكان المحتوى بشكله أثناء التحميل، فلا تتحرك عناصر الصفحة عند وصول المحتوى.
التثبيت
npx @smicolon/fasla-ui@latest add skeletonقبل إضافة أي مكوّن، شغّل الأمر init مرة واحدة في مشروعك. التفاصيل في صفحة التثبيت.
هيكل عنصر القائمة
يضع مكوّن SkeletonListItem صورة رمزية في بداية السطر، وبجانبها أسطر النص على مسافة 16 بكسل. استخدمه للقوائم والتعليقات وصفوف الملفات الشخصية.
هيكل البطاقة
مكوّن SkeletonCard كتلة وسائط بارتفاع 122 بكسل فوق سطرين من النص. ليس له إطار ولا خلفية، فضعه داخل مكوّن بطاقة (Card) إذا كان للمحتوى الحقيقي إطار.
هيكل النص
يرسم مكوّن SkeletonText أسطرًا بعرض كامل، ارتفاع كل منها 16 بكسل وبينها 8 بكسل. يعرض سطرين ما لم تحدد عددها بالخاصية lines.
هيكل الصورة الرمزية
مكوّن SkeletonAvatar دائرة قطرها 48 بكسل. مرّر حجمًا آخر في className ليطابق صورة رمزية أصغر أو أكبر.
ابنِ شكلك الخاص
عندما تحتاج تخطيطًا خارج الهياكل الجاهزة الثلاثة، ركّب شكلك الخاص من كتل مفردة.
كتلة واحدة تحدد حجمها بالخاصية className. تحلّ محلّ مكوّن Skeleton في shadcn/ui دون أي تعديل آخر.
تحدد الخاصية variant شكل الكتلة: شريط بحواف مستديرة بمقدار 4 بكسل، أو دائرة، أو زوايا قائمة.
defaultcircularrectangularإتاحة الوصول (accessibility)
- تحمل كل كتلة السمة (attribute)
aria-hidden، فيتجاوز قارئ الشاشة العناصر النائبة. - ضع السمة (attribute)
aria-busy="true"على المنطقة التي يجري تحميلها، ثم غيّر قيمتها إلىfalseعند وصول المحتوى. - يتوقف النبض إذا فعّل المستخدم إعداد
prefers-reduced-motion. ولإيقافه في كل الحالات، اجعل قيمةanimateهيfalse. - يتبع هيكل التحميل اتجاه الصفحة المحدد في السمة (attribute)
dir، فتظهر الصورة الرمزية دائمًا في بداية السطر.
التعليقات
الخصائص (props)
| الخاصية | النوع | الافتراضي | الوصف |
|---|---|---|---|
variant | "default" | "circular" | "rectangular" | "default" | شكل الكتلة الواحدة: شريط مستدير الحواف، أو دائرة، أو مستطيل. |
animate | boolean | true | يحرّك الهيكل بنبض خفيف أثناء التحميل، ويتوقف النبض دائمًا عند تقليل الحركة. |
lines | number | 2 | عدد أسطر النص في المكوّنات SkeletonText، SkeletonListItem، SkeletonCard. |
className | string | لا يوجد | يحدد الحجم، مثل h-4 w-48. |
الاستخدام
كتلة واحدة
import { Skeleton } from "@/components/ui/skeleton"
export function TitleSkeleton() {
return <Skeleton className="h-4 w-48" />
}أسطر نصية
import { SkeletonText } from "@/components/ui/skeleton"
export function ParagraphSkeleton() {
return <SkeletonText lines={3} />
}صفّ في قائمة
import { SkeletonListItem } from "@/components/ui/skeleton"
export function RowSkeleton() {
return <SkeletonListItem />
}بطاقة
import { SkeletonCard } from "@/components/ui/skeleton"
export function CardSkeleton() {
return <SkeletonCard />
}حدّد المنطقة التي يجري تحميلها
import { SkeletonListItem } from "@/components/ui/skeleton"
interface Comment {
id: number
text: string
}
export function Comments({ comments }: { comments?: Comment[] }) {
const isLoading = comments === undefined
return (
<section aria-busy={isLoading} aria-labelledby="comments">
<h3 id="comments">التعليقات</h3>
{isLoading ? (
<SkeletonListItem />
) : (
<ul>
{comments.map((comment) => (
<li key={comment.id}>{comment.text}</li>
))}
</ul>
)}
</section>
)
}