דילוג לתוכן

אזור גלילה

מכל הניתן לגלילה עם סרגלי גלילה מותאמים אישית התומכים בכל הדפדפנים, המיועד לחלוניות צ'אט, סרגלי צד ועצי קבצים — עם כפתור גלילה גדול בסגנון ניאו-ברוטליסטי.

import * as React from "react"

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

ה-scroll area מחליף את פסי הגלילה של הדפדפן באלה שאתם מעצבים — גלילה מקורית נשארת מתחת, כך שהתנהגות גלגל, מגע ותנופה לא משתנה. נבנה על גבי רכיב Base UI Scroll Area ומעוצב לפי המתכון הנאו-ברוטליסטי: thumb מוצק ועבה בצבע המסגרת וטבעת פוקוס חדה על ה-viewport.

השתמשו בו כש:

  • פאנלי צ'אט ולוגים — מקבעים את הגובה ונותנים להודעות לגלול בתוך הפאנל, לא בעמוד.
  • סרגלי צד ועצי קבצים — רשימות ניווט ארוכות שגוללות בנפרד מהתוכן הראשי.
  • רצועות אופקיות — שורות תגיות, גלריות כרטיסים וטבלאות רחבות דרך 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 ל-viewport כדי שמשתמשי מקלדת יוכלו להגיע ולגלול אותו — הסגנונות כבר כוללים טבעת פוקוס גלויה למקרה הזה. פס הגלילה וה-thumb המותאמים הם אמצעי מצביע בלבד; הם אף פעם לא צריכים להיות הדרך היחידה לגלול.

תיעוד ה-API

למידע נוסף, עיינו בתיעוד של Base UI.