علامات التبويب (Tabs)
يتيح لك مكوّن علامات التبويب (Tabs) التنقل بين عروض مترابطة في المكان نفسه، ويُظهر لوحة واحدة في كل مرة. ويُسمّى المكوّن نفسه أحيانًا Pills.
التثبيت
npx @smicolon/fasla-ui@latest add tabsقبل إضافة أي مكوّن، شغّل الأمر init مرة واحدة في مشروعك. التفاصيل في صفحة التثبيت.
مكوّن علامات التبويب (Tabs) مبني على مكتبة Base UI، لذلك يحتاج إلى الحزمة @base-ui/react. يثبّتها الأمر add مع المكوّن، وكذلك أداة shadcn.
معاينة
الحساب
عدّل بيانات حسابك من هنا.
الأنماط (variant)
تأتي علامات التبويب بثلاثة أنماط (variant)، وتحدد النمط على TabsList حتى لا تختلط الأنماط في مجموعة واحدة. النمط (variant) boxed هو الافتراضي، ويجمع علامات التبويب على خلفية رمادية فاتحة، ويُبرز علامة التبويب النشطة فوقها في إطار مرتفع. وهو مناسب لأشرطة الأدوات والتبديل بين طرق العرض. النمط (variant) bordered يضع خطًا تحت علامة التبويب النشطة، وهو مناسب للتنقل في المحتوى والواجهات المزدحمة. أما النمط (variant) lifted فيرفع علامة التبويب النشطة فوق خط أساسي مثل الملف الورقي، وهو مناسب لأقسام الصفحة الرئيسية.
boxedborderedliftedالأحجام
تتوفر علامات التبويب بثلاثة أحجام، وتحدد الحجم أيضًا على TabsList لتتطابق كل علامات التبويب في المجموعة. الحجم الافتراضي هو md. يبلغ ارتفاع علامة التبويب 28 أو 30 أو 32px، ويستخدم الحجم lg نصًا بحجم 16px مع أيقونات بحجم 20px. وفي النمط (variant) boxed تضيف الخلفية 4px حول علامات التبويب.
smmdlgالحالات
تتبع علامة التبويب النشطة قيمة value. أما حالة التمرير (hover) وحالة التركيز (focus) فتأتيان من CSS مباشرة، لا من خاصية. انتقل إلى المجموعة بمفتاح Tab لترى حلقة التركيز. وتظهر علامة التبويب المعطّلة باهتة، ولا يمكنك اختيارها.
لديك طلبان قيد التوصيل.
لديك طلبان قيد التوصيل.
لديك طلبان قيد التوصيل.
إتاحة الوصول (accessibility)
- يستخدم المكوّن الأدوار الثلاثة
tablist،tab،tabpanel. تشير كل علامة تبويب إلى لوحتها عبر السمة (attribute)aria-controlsما دامت اللوحة ظاهرة، وتأخذ اللوحة اسمها من علامة التبويب عبر السمة (attribute)aria-labelledby. - يدخل مفتاح Tab إلى المجموعة على علامة التبويب النشطة. تنقلك مفاتيح الأسهم إلى علامة التبويب السابقة أو التالية وتختارها، وتعود إلى البداية بعد آخر علامة. لتختار بمفتاح Enter أو مفتاح المسافة بدلًا من ذلك، اجعل قيمة الخاصية
activateOnFocusهيfalse. ينقلك مفتاح Home إلى أول علامة تبويب، ومفتاح End إلى آخرها. وتصل مفاتيح الأسهم إلى علامة التبويب المعطّلة أيضًا ليعلن عنها قارئ الشاشة، لكن لا يمكنك اختيارها. - أضف
aria-labelإلىTabsListليعرف قارئ الشاشة اسم المجموعة. - الأيقونة قبل التسمية زخرفية، فأضف لها
aria-hiddenواترك التسمية تحدد اسم علامة التبويب. - يتبع المكوّن اتجاه الصفحة المحدد في السمة (attribute)
dir، ولا يحتاج إلى خاصية. في الصفحات من اليمين إلى اليسار تتبع الأسهم ترتيب القراءة، فينقلك السهم الأيسر إلى علامة التبويب التالية.
الخصائص (props)
| الخاصية | النوع | الافتراضي | الوصف |
|---|---|---|---|
value | string | لا يوجد | علامة التبويب النشطة عند التحكّم بالقيمة. |
defaultValue | string | لا يوجد | علامة التبويب النشطة في البداية. إذا لم تحدد هذه الخاصية ولا الخاصية value، تكون أول علامة تبويب مفعّلة هي النشطة. |
onValueChange | (value, eventDetails) => void | لا يوجد | تُستدعى عند تغيّر علامة التبويب النشطة. استدعِ eventDetails.cancel() لترفض التغيير. |
variant | "boxed" | "bordered" | "lifted" | "boxed" | شكل علامة التبويب النشطة، ويُحدد على TabsList. |
size | "sm" | "md" | "lg" | "md" | حجم كل علامات التبويب في المجموعة، ويُحدد على TabsList. |
activateOnFocus | boolean | true | تحدد إن كانت مفاتيح الأسهم تختار علامة التبويب التي تنتقل إليها أيضًا، وتُحدد على TabsList. |
TabsTrigger | { value, disabled } | لا يوجد | زر علامة التبويب، وتحدد value لوحته، وتعطّله disabled. |
TabsContent | { value } | لا يوجد | اللوحة التي تظهر لقيمة value. |
className | string | لا يوجد | أصناف (class) إضافية للجزء. |
الاستخدام
علامات تبويب بسيطة
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
export function AccountTabs() {
return (
<Tabs defaultValue="account">
<TabsList aria-label="إعدادات الحساب">
<TabsTrigger value="account">الحساب</TabsTrigger>
<TabsTrigger value="password">كلمة المرور</TabsTrigger>
</TabsList>
<TabsContent value="account">محتوى الحساب هنا.</TabsContent>
<TabsContent value="password">محتوى كلمة المرور هنا.</TabsContent>
</Tabs>
)
}نمط وحجم مختلفان
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
export function BorderedAccountTabs() {
return (
<Tabs defaultValue="account">
<TabsList variant="bordered" size="lg" aria-label="إعدادات الحساب">
<TabsTrigger value="account">الحساب</TabsTrigger>
<TabsTrigger value="password">كلمة المرور</TabsTrigger>
</TabsList>
<TabsContent value="account">محتوى الحساب هنا.</TabsContent>
<TabsContent value="password">محتوى كلمة المرور هنا.</TabsContent>
</Tabs>
)
}مع أيقونة
import { KeyRound, User } from "lucide-react"
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
export function AccountTabsWithIcons() {
return (
<Tabs defaultValue="account">
<TabsList aria-label="إعدادات الحساب">
<TabsTrigger value="account">
<User aria-hidden="true" />
الحساب
</TabsTrigger>
<TabsTrigger value="password">
<KeyRound aria-hidden="true" />
كلمة المرور
</TabsTrigger>
</TabsList>
<TabsContent value="account">محتوى الحساب هنا.</TabsContent>
<TabsContent value="password">محتوى كلمة المرور هنا.</TabsContent>
</Tabs>
)
}التحكّم بالقيمة
"use client"
import { useState } from "react"
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
export function ControlledAccountTabs() {
const [value, setValue] = useState("account")
return (
<Tabs value={value} onValueChange={setValue}>
<TabsList aria-label="إعدادات الحساب">
<TabsTrigger value="account">الحساب</TabsTrigger>
<TabsTrigger value="password">كلمة المرور</TabsTrigger>
</TabsList>
<TabsContent value="account">محتوى الحساب هنا.</TabsContent>
<TabsContent value="password">محتوى كلمة المرور هنا.</TabsContent>
</Tabs>
)
}علامة التبويب النشطة: كلمة المرور