فهرستِ کارهاTask List

یه فهرستِ کارِ کارتی که با تیک‌خوردن پر می‌شه، تیک می‌زنه، متنش رو خط می‌کشه و یه تکانِ ریز می‌خوره؛ کارِ تمام‌شده هم ته صف می‌ره تا کارهای باز بالا بمونن.

محمدجواد

ساخته شده توسط محمدجواد

سازنده فارسی‌فای، بچه دولوپر

وابستگی‌ها

motion

نوع تعامل

روی هر ردیف بزن: خانه پر می‌شه، تیک کشیده می‌شه، متن خط می‌خوره و ردیف یک تکانِ کوتاه می‌خوره؛ متن هم کم‌رنگ می‌شه. ردیفِ تیک‌خورده با اسپرینگ ته صف می‌ره و با برداشتنِ تیک، همان مسیر برمی‌گرده. Space و Enter هم کار می‌کنن و کلیدِ Tab روی ردیف‌ها می‌چرخد. با `prefers-reduced-motion` حرکت حذف می‌شه ولی ترتیبِ مرحله‌ها می‌مونه.

پراپ‌ها

گزینه‌هایی که می‌تونی به کامپوننت بدی؛ ستاره‌دارها اجباری‌اند.

tasks
Task[]پیش‌فرض: [{ id: "a", label: "خرید نان", done: true }]

فهرست در حالتِ کنترل‌شده. هر کار `{ id, label, done? }` است؛ `id` کلیدِ بازچینش است.

defaultTasks
Task[]پیش‌فرض: []

فهرستِ اولیه در حالتِ نام‌کنترل‌شده؛ فقط شروعِ کار را می‌سازد.

onTasksChange
(tasks: Task[]) => void

با هر تیک/برداشتنِ تیک، فهرستِ کاملِ تازه رو برمی‌گردونه.

size
"sm" | "md" | "lg"پیش‌فرض: "md"

اندازه‌ی ردیف و قلم؛ متن از مقیاسِ پروژه می‌آد، نه از عددِ خام.

accent
stringپیش‌فرض: currentColor

رنگِ خانه‌ی پر. هر مقدارِ CSS قبوله؛ پیش‌فرضش رنگِ متنِ ردیف است، پس با تم عوض می‌شه.

checkColor
stringپیش‌فرض: var(--page, #ffffff)

رنگِ خودِ تیک، روی خانه‌ی پر. باید با `accent` کنتراست داشته باشه — پیش‌فرضش رنگِ صفحه است.

نصب

۱. این آدرس رو یک‌بار توی components.json بذار تا shadcn مخزن فارسی‌فای رو بشناسه.

components.jsonjson
{
  "registries": {
    "@farsify": "https://farsify.ir/r/{name}.json"
  }
}

۲. بعد با دستورِ زیر کامپوننت رو نصب کن.

npx shadcn@latest add @farsify/task-list

پیش‌نیاز: Tailwind CSS v4 و صفحهٔ راست‌به‌چپ dir="rtl".

نمونه

task-list.tsxtsx
"use client";

import { useState } from "react";
import { TaskList, type Task } from "@/components/farsify/task-list";

const initial: Task[] = [
  { id: "deps", label: "نصبِ وابستگی‌ها", done: true },
  { id: "registry", label: "ساختِ رجیستری" },
  { id: "rtl", label: "بازبینیِ راست‌چین" },
  { id: "release", label: "انتشارِ نسخه" },
];

export function ReleaseChecklist() {
  const [tasks, setTasks] = useState(initial);

  return (
    <TaskList
      aria-label="کارهای راه‌اندازی"
      tasks={tasks}
      onTasksChange={setTasks}
    />
  );
}

// اندازه‌ی بزرگ‌تر با رنگِ دلخواه برای خانه و تیک
<TaskList
  size="lg"
  defaultTasks={initial}
  accent="#0a84ff"
  checkColor="#ffffff"
/>

// یک ردیفِ تنها، بدونِ بازچینش و بدونِ اعلانِ صفحه‌خوان
import { TaskItem } from "@/components/farsify/task-list";

<TaskItem
  label="انتشارِ نسخه"
  defaultChecked={false}
  onCheckedChange={(done) => console.log(done)}
/>

نکته‌ها

  • برای یک ردیفِ تنها `TaskItem` را مستقیم صادر کن — همان ماشینِ مرحله‌ای را داره، بدونِ بازچینش و بدونِ اعلانِ `aria-live`.
  • `accent` رنگِ خانه است و `checkColor` رنگِ تیک؛ این دو نقش جدا دارن. با پیش‌فرض‌ها در هر دو تم خواناست و لازم نیست چیزی بدی.
  • کارِ تمام‌شده واقعاً در DOM ته صف می‌ره، پس ترتیبِ فوکوس هم با چشم یکی می‌مونه؛ اگه ترتیبِ ثابت می‌خوای، فهرست رو کنترل‌شده بده و خودت مرتب کن.
  • خطِ خوردن از سمتِ start کشیده می‌شه (در راست‌به‌چپ از راست) و تکانِ ردیف هم آینه می‌شه؛ چیزی رو دستی قرینه نکن.
  • هر مرحله با پایانِ انیمیشنِ قبلی جلو می‌ره، نه با تایمر؛ پس با `prefers-reduced-motion` هم ترتیب درست می‌مونه، فقط بی‌حرکت.

مجوز

کد بعد از نصب مالِ خودته؛ هر تغییری خواستی بده و توی پروژه‌ی خودت نگهش دار. برای پروژه‌های شخصی و تجاری آزاده، حتی اگه کدت بسته باشه. فقط اسم و لینک فارسی‌فای رو یه جا توی پروژه نگه دار.