اسپینر (Spinner)
نشاندهنده بارگذاری برای عملیاتهای ناهمزمان.
نصب (Installation)
1npx @quark-lab/rad-ui add spinnerنمونهها (Examples)
استفاده پایه (Basic Usage)
Spinner برای نمایش حالت بارگذاری استفاده میشود.
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2
3export default function BasicExample() {
4 return (
5 <div className="flex items-center justify-center">
6 <Spinner />
7 </div>
8 );
9}
10اندازهها (Sizes)
چهار اندازه مختلف برای موارد مختلف.
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2
3export default function SizesExample() {
4 return (
5 <div className="flex items-end gap-8 justify-center">
6 <div className="flex flex-col items-center gap-2">
7 <Spinner size="sm" />
8 <span className="text-xs text-muted-foreground">کوچک</span>
9 </div>
10 <div className="flex flex-col items-center gap-2">
11 <Spinner size="default" />
12 <span className="text-xs text-muted-foreground">پیشفرض</span>
13 </div>
14 <div className="flex flex-col items-center gap-2">
15 <Spinner size="lg" />
16 <span className="text-xs text-muted-foreground">بزرگ</span>
17 </div>
18 <div className="flex flex-col items-center gap-2">
19 <Spinner size="xl" />
20 <span className="text-xs text-muted-foreground">خیلی بزرگ</span>
21 </div>
22 </div>
23 );
24}
25رنگها (Colors)
میتوانید رنگ اسپینر را با className تغییر دهید.
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2
3export default function ColorsExample() {
4 return (
5 <div className="flex items-center gap-8 justify-center flex-wrap">
6 <div className="flex flex-col items-center gap-2">
7 <Spinner className="text-primary" />
8 <span className="text-xs text-muted-foreground">Primary</span>
9 </div>
10 <div className="flex flex-col items-center gap-2">
11 <Spinner className="text-destructive" />
12 <span className="text-xs text-muted-foreground">Destructive</span>
13 </div>
14 <div className="flex flex-col items-center gap-2">
15 <Spinner className="text-blue-500" />
16 <span className="text-xs text-muted-foreground">Blue</span>
17 </div>
18 <div className="flex flex-col items-center gap-2">
19 <Spinner className="text-green-500" />
20 <span className="text-xs text-muted-foreground">Green</span>
21 </div>
22 <div className="flex flex-col items-center gap-2">
23 <Spinner className="text-purple-500" />
24 <span className="text-xs text-muted-foreground">Purple</span>
25 </div>
26 <div className="flex flex-col items-center gap-2">
27 <Spinner className="text-orange-500" />
28 <span className="text-xs text-muted-foreground">Orange</span>
29 </div>
30 </div>
31 );
32}
33با دکمه (With Button)
نمایش اسپینر در دکمههای در حال بارگذاری.
مشاهده کد
1import { useState } from "react";
2import { Spinner } from "@/components/ui/spinner";
3import { Button } from "@/components/ui/button";
4
5export default function WithButtonsExample() {
6 const [isLoading, setIsLoading] = useState(false);
7
8 const handleClick = () => {
9 setIsLoading(true);
10 setTimeout(() => setIsLoading(false), 2000);
11 };
12
13 return (
14 <div className="flex items-center gap-4 flex-wrap justify-center">
15 <Button disabled>
16 <Spinner size="sm" className="me-2" />
17 در حال بارگذاری...
18 </Button>
19 <Button variant="outline" onClick={handleClick} disabled={isLoading}>
20 {isLoading ? (
21 <>
22 <Spinner size="sm" className="me-2" />
23 لطفاً صبر کنید
24 </>
25 ) : (
26 "کلیک کنید"
27 )}
28 </Button>
29 <Button variant="destructive" disabled>
30 <Spinner size="sm" className="me-2" />
31 در حال حذف...
32 </Button>
33 </div>
34 );
35}
36با متن (With Text)
ترکیب اسپینر با متن توضیحی.
لطفاً صبر کنید
این ممکن است چند لحظه طول بکشد
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2
3export default function WithTextExample() {
4 return (
5 <div className="space-y-4 max-w-md mx-auto">
6 <div className="flex items-center gap-3">
7 <Spinner size="sm" />
8 <span className="text-sm">در حال بارگذاری...</span>
9 </div>
10 <div className="flex items-center gap-3">
11 <Spinner size="default" className="text-primary" />
12 <span>در حال پردازش درخواست شما</span>
13 </div>
14 <div className="flex items-center gap-3">
15 <Spinner size="lg" className="text-blue-500" />
16 <div>
17 <p className="font-medium">لطفاً صبر کنید</p>
18 <p className="text-sm text-muted-foreground">
19 این ممکن است چند لحظه طول بکشد
20 </p>
21 </div>
22 </div>
23 </div>
24 );
25}
26وسطچین (Centered)
نمایش اسپینر در وسط صفحه یا کانتینر.
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2
3export default function CenteredExample() {
4 return (
5 <div className="h-40 flex items-center justify-center">
6 <Spinner size="lg" />
7 </div>
8 );
9}
10مثالهای کاربردی (Practical Examples)
دکمه بارگذاری (Loading Button)
استفاده از اسپینر در دکمهها.
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2import { Button } from "@/components/ui/button";
3
4export default function LoadingButtonExample() {
5 return (
6 <div className="flex items-center gap-4 flex-wrap">
7 <Button>
8 <Spinner size="sm" className="me-2" />
9 ارسال فرم
10 </Button>
11 <Button variant="outline">
12 <Spinner size="sm" className="me-2" />
13 ذخیره تغییرات
14 </Button>
15 <Button variant="ghost">
16 <Spinner size="sm" className="me-2" />
17 بارگذاری بیشتر
18 </Button>
19 </div>
20 );
21}
22بارگذاری صفحه کامل (Full Page Loading)
نمایش وضعیت بارگذاری برای کل صفحه.
در حال بارگذاری
لطفاً چند لحظه صبر کنید...
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2
3export default function FullPageExample() {
4 return (
5 <div className="h-64 flex flex-col items-center justify-center gap-4">
6 <Spinner size="xl" className="text-primary" />
7 <div className="text-center">
8 <p className="font-medium mb-1">در حال بارگذاری</p>
9 <p className="text-sm text-muted-foreground">
10 لطفاً چند لحظه صبر کنید...
11 </p>
12 </div>
13 </div>
14 );
15}
16بارگذاری درونخطی (Inline Loading)
نمایش وضعیت بارگذاری در کنار متن.
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2
3export default function InlineExample() {
4 return (
5 <div className="max-w-md space-y-4">
6 <div className="p-4 rounded-lg bg-muted/50">
7 <div className="flex items-center justify-between">
8 <span className="text-sm">در حال آپلود فایل...</span>
9 <Spinner size="sm" />
10 </div>
11 <div className="mt-2 h-2 bg-background rounded-full overflow-hidden">
12 <div className="h-full bg-primary w-2/3 rounded-full" />
13 </div>
14 </div>
15 <div className="p-4 rounded-lg bg-muted/50">
16 <div className="flex items-center justify-between">
17 <span className="text-sm">در حال پردازش تصویر...</span>
18 <Spinner size="sm" className="text-blue-500" />
19 </div>
20 </div>
21 </div>
22 );
23}
24اورلی بارگذاری کارت (Card Loading Overlay)
نمایش اسپینر روی کارت هنگام بهروزرسانی.
اطلاعات کاربر
نام: علی محمدی
ایمیل: ali@example.com
تلفن: 09123456789
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2
3export default function CardOverlayExample() {
4 return (
5 <div className="max-w-sm mx-auto relative">
6 <div className="p-6 rounded-lg border border-border">
7 <h4 className="font-semibold mb-2">اطلاعات کاربر</h4>
8 <div className="space-y-2 text-sm text-muted-foreground">
9 <p>نام: علی محمدی</p>
10 <p>ایمیل: ali@example.com</p>
11 <p>تلفن: 09123456789</p>
12 </div>
13 </div>
14 <div className="absolute inset-0 bg-background/80 backdrop-blur-sm rounded-lg flex items-center justify-center">
15 <div className="flex flex-col items-center gap-2">
16 <Spinner size="lg" />
17 <span className="text-sm font-medium">در حال بهروزرسانی...</span>
18 </div>
19 </div>
20 </div>
21 );
22}
23ارسال فرم (Form Submission)
غیرفعال کردن فرم هنگام ارسال.
مشاهده کد
1import { Spinner } from "@/components/ui/spinner";
2import { Button } from "@/components/ui/button";
3
4export default function FormSubmissionExample() {
5 return (
6 <div className="max-w-md mx-auto space-y-4">
7 <div className="space-y-2">
8 <label className="text-sm font-medium">نام</label>
9 <input
10 type="text"
11 className="flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm"
12 placeholder="نام خود را وارد کنید"
13 disabled
14 />
15 </div>
16 <div className="space-y-2">
17 <label className="text-sm font-medium">ایمیل</label>
18 <input
19 type="email"
20 className="flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm"
21 placeholder="your@email.com"
22 disabled
23 />
24 </div>
25 <Button className="w-full" disabled>
26 <Spinner size="sm" className="me-2" />
27 در حال ارسال...
28 </Button>
29 </div>
30 );
31}
32مرجع API (API Reference)
Spinner
پراپهای کامپوننت Spinner.
| پراپ (Prop) | نوع (Type) | پیشفرض (Default) | توضیحات (Description) |
|---|---|---|---|
size | "sm" | "default" | "lg" | "xl" | "default" | اندازه اسپینر |
className | string | undefined | کلاسهای CSS سفارشی (برای رنگ) |
srText | string | "Loading..." | متن برای اسکرین ریدرها |
دسترسیپذیری (Accessibility)
role و aria-label
اسپینر به صورت خودکار role="status" و aria-label دارد
متن اسکرین ریدر
یک sr-only span برای اسکرین ریدرها اضافه شده است
سفارشیسازی متن
میتوانید متن اسکرین ریدر را با prop srText تغییر دهید
بهترین شیوهها (Best Practices)
کی از Spinner استفاده کنیم؟
از Spinner زمانی استفاده کنید که عملیاتی در حال انجام است و کاربر باید منتظر بماند (مثل ارسال فرم، بارگذاری داده، یا پردازش)
متن توضیحی
همیشه یک متن توضیحی همراه اسپینر قرار دهید تا کاربر بداند چه اتفاقی در حال رخ دادن است
اندازه مناسب
از اندازه مناسب برای محیط استفاده کنید: sm برای دکمهها، default برای کارتها، lg/xl برای صفحات کامل
غیرفعال کردن تعامل
هنگام نمایش اسپینر، دکمهها و فرمها را غیرفعال کنید تا از ارسال مجدد جلوگیری شود
زمانبندی
برای عملیاتهای سریع (کمتر از 500ms) ممکن است نمایش اسپینر نیاز نباشد. برای عملیاتهای طولانی، پیشرفت را نشان دهید