Bỏ qua đến nội dung

Vòng tải

Một chỉ báo tải động dành cho các thao tác gửi, truy xuất đang chờ xử lý và các trạng thái bận trong nội dung — một biểu tượng có thể tích hợp ngay vào bất kỳ thành phần điều khiển theo phong cách neobrutalist nào.

import {
  Item,
  ItemContent,

Spinner là một biểu tượng động duy nhất báo hiệu một thao tác đang diễn ra. Nó bọc LoaderIcon từ lucide-react với animate-spin và có sẵn role="status" cùng một aria-label — không dùng thư viện primitive nào, nên cả hai backend dùng chung một cách triển khai, và nó kế thừa currentColor để hòa màu với bất kỳ điều khiển neobrutalist nào chứa nó.

Nên dùng khi:

  • Gửi đang chờ xử lý — hoán đổi nó vào nút trong lúc mutation chạy; nhãn vẫn giữ nguyên chỗ.
  • Trạng thái tải trong dòng — badge, nhóm input và ô bảng đang chờ dữ liệu.
  • Tải theo từng khu vực — ghép nó với Empty trong lúc một panel đang stream về.

Cài đặt

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

Sao chép và dán đoạn mã sau vào dự án của bạn.

components/ui/spinner.tsx
import { Loader2Icon } from "lucide-react"

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

function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
  return (
    <Loader2Icon
      data-slot="spinner"
      role="status"
      aria-label="Loading"
      className={cn("size-4 animate-spin", className)}
      {...props}
    />
  )
}

export { Spinner }

Cập nhật các đường dẫn import cho phù hợp với cấu hình dự án của bạn.

Cách dùng

import { Spinner } from "@/components/ui/spinner"
<Spinner />

Tùy chỉnh

Bạn có thể thay thế icon spinner mặc định bằng bất kỳ icon nào khác bằng cách chỉnh sửa component Spinner.

import { LoaderIcon } from "lucide-react"

import { cn } from "@/lib/utils"
components/ui/spinner.tsx
import { LoaderIcon } from "lucide-react"
 
import { cn } from "@/lib/utils"
 
function Spinner({ className, ...props }: React.ComponentProps<"svg">) {
  return (
    <LoaderIcon
      role="status"
      aria-label="Loading"
      className={cn("size-4 animate-spin", className)}
      {...props}
    />
  )
}
 
export { Spinner }

Ví dụ

Kích thước

Dùng lớp tiện ích size-* để thay đổi kích thước của spinner.

import { Spinner } from "@/components/ui/spinner"

export function SpinnerSize() {

Button

Thêm một spinner vào nút để cho biết trạng thái đang tải. Đặt <Spinner /> trước nhãn với data-icon="inline-start" cho vị trí đầu, hoặc sau nhãn với data-icon="inline-end" cho vị trí cuối.

import { Button } from "@/components/ui/button"
import { Spinner } from "@/components/ui/spinner"

Badge

Thêm một spinner vào badge để cho biết trạng thái đang tải. Đặt <Spinner /> trước nhãn với data-icon="inline-start" cho vị trí đầu, hoặc sau nhãn với data-icon="inline-end" cho vị trí cuối.

import { Badge } from "@/components/ui/badge"
import { Spinner } from "@/components/ui/spinner"

Input Group

import { ArrowUpIcon } from "lucide-react"

import {

Empty

import { Button } from "@/components/ui/button"
import {
  Empty,

RTL

Để bật hỗ trợ RTL trong Neobrutalism, xem hướng dẫn cấu hình RTL.

"use client"

import * as React from "react"

Khả năng truy cập

Spinner render role="status" với aria-label="Loading", nên trình đọc màn hình đọc lên trạng thái đang tải mà không cần nối thêm gì. Khi văn bản kế bên đã mô tả trạng thái đó (“Đang lưu…”), hãy truyền aria-hidden="true" cho spinner — một lần thông báo là đủ. Với cả một vùng chuyển sang trạng thái đang tải, hãy đặt aria-busy="true" trên phần tử chứa.