مجموعة تبديل
مجموعات أزرار ذات حالتين لشريط أدوات المحرر، ومبدلات العرض، وأشرطة التصفية — مع تطبيق أسلوب «النيوبروتاليست» في الحدود والظلال.
import { Bold, Italic, Underline } from "lucide-react"
import {مجموعة التبديل عبارة عن صف من الأزرار ذات الحالتين، حيث يمكن الضغط على زر واحد (الوضع الافتراضي) أو عدة أزرار (multiple) في آن واحد. وهي مبنية على مكون Base UI Toggle Group ومصممة وفقًا لنهج «النيوبروتالية»: حدود سميكة، وظلال حادة، وخط عريض.
استخدمه عندما:
- أشرطة أدوات المحرر — الخط العريض/المائل/التسطير، ومحاذاة النص، وأنماط القوائم باستخدام
multiple. - مبدلات العرض — الشبكة مقابل القائمة، والرسم البياني مقابل الجدول، واليوم/الأسبوع/الشهر؛ حيث يُبقي الإعداد الافتراضي على نشاط عنصر واحد كحد أقصى.
- أشرطة التصفية — العلامات أو الفئات أو المعايير التي يمكن للمستخدم تفعيلها أو إلغاء تفعيلها.
التثبيت#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/toggle-group.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/toggle-group.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/toggle-group.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/toggle-group.json
ثبّت التبعيات التالية:
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
انسخ الكود التالي والصقه في مشروعك.
"use client"
import * as React from "react"
import { type VariantProps } from "class-variance-authority"
import { ToggleGroup as ToggleGroupPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
import { toggleVariants } from "@/components/ui/toggle"
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants> & {
spacing?: number
orientation?: "horizontal" | "vertical"
}
>({
size: "default",
variant: "default",
spacing: 2,
orientation: "horizontal",
})
function ToggleGroup({
className,
variant,
size,
spacing = 2,
orientation = "horizontal",
children,
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants> & {
spacing?: number
orientation?: "horizontal" | "vertical"
}) {
return (
<ToggleGroupPrimitive.Root
data-slot="toggle-group"
data-variant={variant}
data-size={size}
data-spacing={spacing}
data-orientation={orientation}
style={{ "--gap": spacing } as React.CSSProperties}
className={cn(
"group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-vertical:flex-col data-vertical:items-stretch",
className
)}
{...props}
>
<ToggleGroupContext.Provider
value={{ variant, size, spacing, orientation }}
>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
)
}
function ToggleGroupItem({
className,
children,
variant = "default",
size = "default",
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>) {
const context = React.useContext(ToggleGroupContext)
return (
<ToggleGroupPrimitive.Item
data-slot="toggle-group-item"
data-variant={context.variant || variant}
data-size={context.size || size}
data-spacing={context.spacing}
className={cn(
"shrink-0 group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 focus:z-10 focus-visible:z-10 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t",
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
}),
className
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
)
}
export { ToggleGroup, ToggleGroupItem }
حدّث مسارات الاستيراد لتطابق إعداد مشروعك.
الاستخدام#
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"<ToggleGroup type="single">
<ToggleGroupItem value="a">A</ToggleGroupItem>
<ToggleGroupItem value="b">B</ToggleGroupItem>
<ToggleGroupItem value="c">C</ToggleGroupItem>
</ToggleGroup>التركيب#
استخدم التركيب التالي لبناء ToggleGroup:
ToggleGroup
├── ToggleGroupItem
└── ToggleGroupItemأمثلة#
إطار#
استخدم variant="outline" للحصول على نمط بإطار.
import {
ToggleGroup,
ToggleGroupItem,الحجم#
استخدم الخاصية size لتغيير حجم مجموعة التبديل.
import {
ToggleGroup,
ToggleGroupItem,التباعد#
استخدم spacing لإضافة تباعد بين عناصر مجموعة التبديل.
import {
ToggleGroup,
ToggleGroupItem,عمودي#
استخدم orientation="vertical" لمجموعات التبديل العمودية.
import { BoldIcon, ItalicIcon, UnderlineIcon } from "lucide-react"
import {معطّل#
import { Bold, Italic, Underline } from "lucide-react"
import {مخصّص#
مثال على مجموعة تبديل مخصّصة.
"use client"
import * as React from "react"RTL#
لتفعيل RTL في Neobrutalism، راجع دليل إعداد RTL.
"use client"
import * as React from "react"إمكانية الوصول#
كل عنصر هو زر تبديل وفقًا لـ WAI-ARIA Button pattern: حيث تعرض المجموعة role="group"، ويكون كل عنصر عبارة عن <button> حقيقي مع aria-pressed، سواء في الوضع الفردي أو المتعدد. يستخدم التركيز مؤشر تبويب متنقل، لذا فإن المجموعة بأكملها تمثل نقطة توقف واحدة لـ Tab. العناصر التي تحتوي على أيقونة فقط تحتاج إلى aria-label.
تفاعلات لوحة المفاتيح:
| مفتاح | الإجراء |
|---|---|
Tab / Shift + Tab | نقل التركيز إلى المجموعة وخارجها |
Space / Enter | تبديل العنصر الذي يقع عليه التركيز |
ArrowRight / ArrowDown | نقل التركيز إلى العنصر التالي |
ArrowLeft / ArrowUp | نقل التركيز إلى العنصر السابق |
Home / End | الانتقال إلى العنصر الأول / الأخير |
مرجع API#
لمزيد من المعلومات، راجع وثائق Base UI.
سجل التغييرات#
2026-05-17 التباعد الافتراضي#
تم تغيير القيمة الافتراضية لـ spacing من 0 إلى 2 بحيث تُعرض مجموعات التبديل مع تباعد بين العناصر افتراضياً. استخدم spacing={0} للعناصر المتّصلة.