مفتاح التبديل (Switch)

يتيح لك مكوّن مفتاح التبديل (Switch) تشغيل إعداد أو إيقافه.

التثبيت

bash
npx @smicolon/fasla-ui@latest add switch

قبل إضافة أي مكوّن، شغّل الأمر init مرة واحدة في مشروعك. التفاصيل في صفحة التثبيت.

معاينة

الأنماط (variant)

يأتي مفتاح التبديل بنمطين (variant) كما في Figma. النمط (variant) solid هو الافتراضي، ويملأ المسار باللون الأساسي عند التشغيل. أما النمط (variant) outline فيُبقي المسار بلون خلفية الصفحة ويرسم حوله خطًا بسماكة 1px، ويلوّن المقبض بدلًا منه.

solid
outline

الأحجام

يتوفر مفتاح التبديل بثلاثة أحجام، والحجم الافتراضي هو md. يبلغ عرض المسار 32 أو 40 أو 48px، ويبقى حجم التسمية ثابتًا.

solid
outline

التخطيط (layout)

في التخطيط (layout) الافتراضي control-first يأتي المسار قبل التسمية، ويبدأ الوصف تحت التسمية مباشرة. أما التخطيط (layout) label-first فيضع التسمية في بداية سطر بعرض كامل والمسار في نهايته، وهو مناسب لقوائم الإعدادات.

control-first
label-first

الحالات

تأتي حالة التركيز (focus) من CSS مباشرة، لا من خاصية. انتقل إلى مفتاح التبديل بمفتاح Tab لترى حلقة التركيز. وعند التعطيل يظهر المكوّن كله باهتًا، بما فيه التسمية والوصف.

solid
outline

إتاحة الوصول (accessibility)

  • يعمل مفتاح التبديل مع لوحة المفاتيح تلقائيًا: تبدّل حالته بمفتاح المسافة، ويُرسَل مع النموذج دون شيفرة إضافية، لأنه مبني على عنصر <input type="checkbox" role="switch"> الأصلي.
  • يقرأ قارئ الشاشة نص description بعد التسمية مباشرة، لأنه مرتبط بمفتاح التبديل عبر aria-describedby. أما المسار المرسوم فمخفي عن قارئ الشاشة.
  • أضف aria-label لمفتاح التبديل الذي يظهر بلا label، ليعرف قارئ الشاشة ما يتحكم فيه.
  • يتبع مفتاح التبديل اتجاه الصفحة المحدد في السمة (attribute) dir، فيتحرك المقبض دائمًا نحو نهاية السطر عند التشغيل.

الخصائص (props)

الخاصيةالنوعالافتراضيالوصف
variant"solid" | "outline""solid"مسار مملوء أو مسار بإطار.
layout"control-first" | "label-first""control-first"المسار قبل التسمية أو بعدها.
size"sm" | "md" | "lg""md"حجم مفتاح التبديل.
checkedbooleanلا يوجدحالة التشغيل، وتُستخدم مع onChange.
defaultCheckedbooleanfalseالحالة الأولى عندما لا تتحكم بالقيمة.
disabledbooleanfalseيعطّل المفتاح ويُظهره باهتًا.
labelstringلا يوجدنص التسمية.
descriptionstringلا يوجدسطر ثانوي تحت التسمية.
namestringلا يوجدالاسم الذي يُرسَل مع النموذج.
onChange(event) => voidلا يوجدتُستدعى عند تغيير حالة المفتاح.
classNamestringلا يوجدأصناف (class) إضافية للمكوّن.

الاستخدام

مفتاح تبديل بسيط

tsx
import { Switch } from "@/components/ui/switch"

export function AirplaneModeSwitch() {
  return <Switch name="airplane" aria-label="وضع الطيران" />
}

مع تسمية

tsx
import { Switch } from "@/components/ui/switch"

export function AirplaneModeSwitch() {
  return <Switch name="airplane" label="وضع الطيران" defaultChecked />
}

مع وصف

tsx
import { Switch } from "@/components/ui/switch"

export function DarkModeSwitch() {
  return (
    <Switch
      name="dark-mode"
      label="الوضع الداكن"
      description="شغّل الوضع الداكن أو أوقفه"
    />
  )
}

النمط (variant) outline

tsx
import { Switch } from "@/components/ui/switch"

export function AutoSyncSwitch() {
  return <Switch name="auto-sync" variant="outline" label="المزامنة التلقائية" />
}

التسمية أولًا والمسار في النهاية

tsx
import { Switch } from "@/components/ui/switch"

export function NotificationsSwitch() {
  return <Switch name="notifications" layout="label-first" label="الإشعارات" />
}

أحجام مختلفة

tsx
import { Switch } from "@/components/ui/switch"

export function SwitchSizes() {
  return (
    <div className="flex flex-col gap-4">
      <Switch size="sm" label="صغير" />
      <Switch size="md" label="متوسط" />
      <Switch size="lg" label="كبير" />
    </div>
  )
}

التحكّم بالقيمة

tsx
"use client"

import { useState } from "react"
import { Switch } from "@/components/ui/switch"

export function ControlledNotificationsSwitch() {
  const [enabled, setEnabled] = useState(true)

  return (
    <Switch
      name="notifications"
      label="الإشعارات"
      checked={enabled}
      onChange={(e) => setEnabled(e.target.checked)}
    />
  )
}

الحالة الحالية: قيد التشغيل