الانتقال إلى المحتوى

منطقة تمرير

حاوية قابلة للتمرير مزودة بأشرطة تمرير مخصصة ومتوافقة مع جميع المتصفحات، مخصصة لأجزاء الدردشة والأشرطة الجانبية وشجرات الملفات — مع مؤشر تمرير سميك على الطراز «النيوبروتالستي».

import * as React from "react"

import { ScrollArea } from "@/components/ui/scroll-area"

تحل منطقة التمرير محل أشرطة التمرير الافتراضية للمتصفح بأخرى تصممها بنفسك — بينما تظل وظيفة التمرير الأصلية موجودة في الخلفية، لذا لا يتأثر سلوك التمرير باستخدام عجلة الماوس أو اللمس أو الزخم. تم بناؤها على مكون Base UI Scroll Area وتصميمها وفقًا لنهج «النيوبروتالية»: زر تمرير صلب وضخم بلون الحدود وحلقة تركيز بارزة على نافذة العرض.

استخدمه عندما:

  • أجزاء الدردشة والسجل — قم بتثبيت الارتفاع واجعل الرسائل تتحرك داخل اللوحة، وليس داخل الصفحة.
  • الأشرطة الجانبية وشجرات الملفات — قوائم التنقل الطويلة التي يتم تمريرها بشكل مستقل عن المحتوى الرئيسي.
  • الشرائط الأفقية — صفوف العلامات، ومعارض البطاقات، والجداول العريضة عبر orientation="horizontal".

التثبيت

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/scroll-area.json
npx shadcn@latest add https://neobrutalism.com/r/base/scroll-area.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/scroll-area.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/scroll-area.json

ثبّت التبعيات التالية:

pnpm add @base-ui/react
npm install @base-ui/react
yarn add @base-ui/react
bun add @base-ui/react

انسخ الكود التالي والصقه في مشروعك.

components/ui/scroll-area.tsx
"use client"

import * as React from "react"
import { ScrollArea as ScrollAreaPrimitive } from "radix-ui"

import { cn } from "@/lib/utils"

function ScrollArea({
  className,
  children,
  ...props
}: React.ComponentProps<typeof ScrollAreaPrimitive.Root>) {
  return (
    <ScrollAreaPrimitive.Root
      data-slot="scroll-area"
      className={cn("relative", className)}
      {...props}
    >
      <ScrollAreaPrimitive.Viewport
        data-slot="scroll-area-viewport"
        className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary"
      >
        {children}
      </ScrollAreaPrimitive.Viewport>
      <ScrollBar />
      <ScrollAreaPrimitive.Corner />
    </ScrollAreaPrimitive.Root>
  )
}

function ScrollBar({
  className,
  orientation = "vertical",
  ...props
}: React.ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
  return (
    <ScrollAreaPrimitive.ScrollAreaScrollbar
      data-slot="scroll-area-scrollbar"
      data-orientation={orientation}
      orientation={orientation}
      className={cn(
        "flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent",
        className
      )}
      {...props}
    >
      <ScrollAreaPrimitive.ScrollAreaThumb
        data-slot="scroll-area-thumb"
        className="relative flex-1 rounded bg-border"
      />
    </ScrollAreaPrimitive.ScrollAreaScrollbar>
  )
}

export { ScrollArea, ScrollBar }

حدّث مسارات الاستيراد لتتوافق مع بنية مشروعك.

الاستخدام

import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area"
<ScrollArea className="h-[200px] w-[350px] rounded-md border p-4">
  Your scrollable content here.
</ScrollArea>

التركيب

استخدم التركيب التالي لبناء ScrollArea:

ScrollArea
└── ScrollBar

أمثلة

أفقي

استخدم ScrollBar مع orientation="horizontal" للتمرير الأفقي.

import * as React from "react"
import Image from "next/image"

RTL

لتفعيل RTL في Neobrutalism، راجع دليل إعداد RTL.

"use client"

import * as React from "react"

إمكانية الوصول

لا يوجد نمط WAI-ARIA لمناطق التمرير — ولا حاجة إلى ذلك، لأن مكون «Base UI» يحتفظ بحاوية تمرير أصلية حقيقية في الخلفية، لذا فإن التمرير باستخدام عجلة الماوس أو اللمس أو لوحة المفاتيح يعمل تمامًا كما هو الحال في المتصفح نفسه. لا تتيح جميع المتصفحات إمكانية التركيز على حاوية التمرير باستخدام لوحة المفاتيح من تلقاء نفسها: إذا كان المحتوى لا يحتوي على عناصر قابلة للتركيز، فقم بإضافة tabIndex={0} و aria-label إلى نافذة العرض حتى يتمكن مستخدمو لوحة المفاتيح من الوصول إليها والتمرير فيها — تتضمن الأنماط بالفعل حلقة تركيز مرئية لهذه الحالة. شريط التمرير المخصص ومقبض التمرير هما وسيلتان للتفاعل تعتمدان على المؤشر فقط؛ ولا يجب أبدًا أن يكونا الطريقة الوحيدة للتمرير.

مرجع API

لمزيد من المعلومات، راجع وثائق Base UI.