نوار ابزار جدول داده (DataTableToolbar)

دو ابزار جانبی DataTable — Column Visibility dropdown + Export به CSV/TSV

معرفی

دو کامپوننت جانبی برای استفاده در toolbar بالای DataTable. هر دو روی API های موجود DataTable (columnVisibility prop) و export utilityها (CSV/TSV builders) سوار شده‌اند.

چه زمانی استفاده کنیم:

  • برای جدول‌های ستون‌زیاد که کاربر باید ستون‌های نمایشی را خودش انتخاب کند (مانند گزارش کمپین تخفیف فصلی با ده‌ها ستون متریک)
  • زمانی که کاربر به خروجی داده‌ی جدول نیاز دارد — CSV برای Excel یا کپی TSV برای paste در Sheets/Notion
  • وقتی می‌خواهید کنترل‌های جدول را در یک نوار ابزار واحد و یکدست بالای DataTable جمع کنید

چه زمانی استفاده نکنیم:

  • برای جدول‌های کوچک با ستون‌های ثابت و اندک — dropdown مدیریت ستون فقط پیچیدگی اضافه می‌کند
  • برای خروجی PDF یا XLSX — این کامپوننت فقط CSV/TSV تولید می‌کند؛ از کتابخانه‌ی external با یک Button معمولی استفاده کنید
  • وقتی export باید سمت سرور انجام شود — DataTableExportButton فقط همان data سمت کلاینت را serialize می‌کند؛ در جدول‌های server-paged یعنی فقط صفحه‌ی جاری

زمین بازی

با تغییر variant و size، نوار ابزار را به‌صورت زنده مشاهده کنید.

زمین بازی
تنظیمات
ظاهر
محتوا
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.

استفاده

import { DataTable, DataTableColumnVisibilityToggle, DataTableExportButton } from '@partodata/ui'

هر دو کامپوننت controlled و بدون state داخلی هستند: DataTableColumnVisibilityToggle همان object مربوط به columnVisibility را دریافت می‌کند که به خود DataTable می‌دهید، و DataTableExportButton همان تعاریف columns و data جدول را (در صورت نیاز با exportValue برای سلول‌های React-element). روی صفحهٔ فهرست هر دو propهای قالب ListPage هستند و جدول فرزند آن است: DataTableExportButton در secondaryActions (بدون variant: آن‌جا default رندر می‌شود، مثل همهٔ اقدام‌های ثانوی) و DataTableColumnVisibilityToggle در toolbarEnd، فقط وقتی محصول انتخاب ستون‌ها را می‌خواهد (نه در filters). قالب آن‌ها را با بقیهٔ کنترل‌ها هم‌قد می‌کند (بیرون از صفحه پیش‌فرضشان xs است). جزئیات API و مثال هر کدام در دو بخش بعدی آمده است.

DataTableColumnVisibilityToggle

Dropdown با checkbox برای روشن/خاموش کردن هر ستون + دکمه‌ی Reset.

import { DataTable, DataTableColumnVisibilityToggle } from '@partodata/ui'
import { ListPage, pageState } from '@partodata/ui/templates'

const [visible, setVisible] = React.useState<Record<string, boolean>>({})
const visibility = { visible, onVisibilityChange: setVisible }

// در صفحهٔ فهرست: در toolbarEnd قالب (کنترل خود فهرست)؛ جدول فرزند ListPage است، بدون size، pagination و حالت‌های خودش
;<ListPage
  title="اینفلوئنسرها"
  toolbarEnd={<DataTableColumnVisibilityToggle columns={columns} visibility={visibility} />}
  state={pageState({
    data: data?.items,
    isLoading,
    error,
    onRetry: load,
    emptyCopy: { title: 'هنوز اینفلوئنسری ثبت نشده است' },
  })}
>
  <DataTable columns={columns} data={data?.items ?? []} columnVisibility={visibility} />
</ListPage>

DataTableExportButton

Dropdown با دو گزینه: Download CSV (فایل با BOM-prefixed UTF-8، مناسب Excel فارسی) و Copy as TSV (کلیپبورد، مناسب paste به Sheets/Notion). از buildCsv / buildTsv / downloadFile helpers هم به‌صورت standalone export شده‌اند.

import { DataTableExportButton } from '@partodata/ui'
;<DataTableExportButton
  filename="comments-2026-04.csv"
  data={rows}
  columns={[
    { id: 'name', header: 'نام', cell: (r) => r.name, exportValue: (r) => r.name },
    { id: 'sentiment', header: 'احساس', cell: (r) => r.sentiment, exportValue: (r) => r.sentiment },
    { id: 'count', header: 'تعداد', cell: (r) => r.count, exportValue: (r) => r.count },
  ]}
/>

ستون‌ها از همان DataTableColumn معمول استفاده می‌کنند (id + header + cell). اگر می‌خواهید مقدار export شده با مقدار رندر تفاوت داشته باشد، exportValue را تعریف کنید — در غیر این صورت cell به‌صورت پیش‌فرض serialize می‌شود.

برای PDF/Excel xlsx، DS قصد ندارد library سنگین وارد کند — از npm package های external استفاده کنید (xlsx، pdfmake) و آنها را با خود <Button> invoke کنید.

روی صفحه‌ای که با یکی از قالب‌های صفحه ساخته شده (هر صفحه)، وقتی data خالی است (فهرست هنوز بار نشده، نتیجه‌ای نیافته یا خطا داده)، خود قالب دکمه را غیرفعال می‌کند و دلیلش را می‌گوید: aria-disabled (در ترتیب Tab می‌ماند)، کم‌رنگ، دلیل «خروجی وقتی ممکن است که فهرست دست‌کم یک ردیف داشته باشد» در راهنمای ابزار با hover، فوکوس و لمس و به‌عنوان توضیح دکمه، و منویش باز نمی‌شود (دیگر فایل CSV بی‌ردیف دانلود نمی‌شود). این در هر جای صفحه است: secondaryActions، actions یک بخش، یا محتوای صفحه. پس خروجی جدول همیشه بی هیچ شرطی نوشته می‌شود: نه GatedAction روی تعداد ردیف‌ها، نه disabled، نه rows.length > 0 && … (قاعدهٔ ESLint parto/page-primary-action هر سه را نشان می‌دهد). وقتی ردیف‌ها می‌رسند همان دکمه فعال می‌شود و فوکوس رویش می‌ماند. بیرون از قالب صفحه (مثلاً در نمونه‌های مستقل همین صفحه) دکمه روی ردیف‌هایش بسته نمی‌شود.

propهای دیگر دکمه (و ref) همان‌طور که هستند به دکمهٔ trigger می‌رسند؛ disabled جزو آن‌ها نیست. خروجی‌ای که کاربر اجازه‌اش را ندارد (یا سهمیه‌اش تمام شده) فرزند GatedAction می‌شود: همان دکمه aria-disabled با دلیل همان GatedAction است و منویش با کلیک، Enter یا پیکان پایین باز نمی‌شود:

<GatedAction allowed={canExport} reason="خروجی گرفتن فقط برای اعضای فضای کار ممکن است">
  <DataTableExportButton columns={columns} data={rows} filename="mentions.csv" label="خروجی CSV" />
</GatedAction>

راهنمای استفاده

بکنید

  • روی صفحهٔ فهرست DataTableExportButton را در secondaryActions و DataTableColumnVisibilityToggle را در toolbarEnd قالب ListPage بگذارید، بدون variant، نه در یک div با flex که خودتان می‌سازید - برای محتوای فارسی، CSV با BOM-UTF8 prefix را Excel درست باز می‌کند — این کامپوننت پیش‌فرض همین کار را می‌کند - برای داده‌ی بزرگ، در کلیک export یک Toast با progress نمایش دهید — کاربر هیچ feedback ندارد

نکنید

  • PDF/XLSX را در lib bundle نکنید — تخصصی است و سنگین — به‌صورت optional dep در consumer install کنید - در ExportButton مقدار خام accessor با کاما/نقل قول را escape کنید — buildCsv و buildTsv این کار را خودکار انجام می‌دهند؛ فقط همین helperهای عمومی (buildCsv / buildTsv / downloadFile) export شده‌اند، پس منطق escape را دور نزنید

جدول ویژگی‌ها

DataTableColumnVisibilityToggle

Prop

Type

DataTableExportButton

Prop

Type

Helperهای standalone

  • buildCsv(columns, data) → string — تولید CSV با escape مناسب (کاما، نقل قول، newline)
  • buildTsv(columns, data) → string — تولید TSV (tab-separated)
  • downloadFile(filename, content, mime?) — trigger دانلود مرورگر با BOM برای UTF-8

دسترسی‌پذیری

  • هر دو روی Radix DropdownMenu ساخته شده‌اند — open/close با Enter/Space روی trigger، navigation با Arrow keys، Escape برای close.
  • آیکون‌های Settings2 و Download با aria-hidden="true" رندر می‌شوند؛ متن دکمه (label یا locale-aware fallback) مسئول a11y است.
  • DropdownMenuCheckboxItem در ColumnVisibilityToggle خود role="menuitemcheckbox" و aria-checked معنادار را تأمین می‌کند.
  • پس از انتخاب CSV/TSV، menu بسته می‌شود ولی هیچ live announcement خودکار نیست؛ برای داده‌ی بزرگ یک Toast با feedback نمایش دهید (به راهنمای استفاده مراجعه کنید).
  • خروجی بی‌ردیف، و خروجی‌ای که درون GatedAction بسته شده، aria-disabled است (در ترتیب Tab می‌ماند و دلیلش را به‌عنوان توضیح می‌خواند) و منویی باز نمی‌کند؛ وقتی در دسترس می‌شود همان دکمه می‌ماند و فوکوس از آن نمی‌رود.
  • در RTL، align="end" روی DropdownMenuContent به سمت start منطقی align می‌شود — physical right/left استفاده نشده.

کامپوننت‌های مرتبط