پرتوپرتو

جدول با مرتب‌سازی

الگوی جدول داده‌ای با ستون‌های قابل مرتب‌سازی و نشانگر aria-sort

معرفی

این الگو نشان می‌دهد چگونه یک جدول با مرتب‌سازی بسازید که:

  • از TableSortHeader برای دکمه‌های مرتب‌سازی استفاده می‌کند
  • aria-sort را برای دسترسی‌پذیری روی ستون‌ها تنظیم می‌کند
  • وضعیت مرتب‌سازی را در state مدیریت می‌کند

نمونه بصری

نامدنبال‌کنندگاننرخ تعامل
علی محمدی۱۲٬۵۰۰۴.۲٪
سارا احمدی۸۷٬۳۰۰۳.۱٪
رضا کریمی۲۳۴٬۰۰۰۲.۸٪
مریم حسینی۵٬۲۰۰۶.۷٪
امیر رضایی۴۵٬۸۰۰۳.۵٪

کد کامل

'use client'

import { useState } from 'react'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, TableSortHeader } from '@parto-system-design/ui'

type SortDirection = 'asc' | 'desc' | null
type SortColumn = 'name' | 'followers' | 'engagementRate' | null

interface Influencer {
  id: number
  name: string
  followers: number
  engagementRate: number
}

const data: Influencer[] = [
  { id: 1, name: 'محمد رضایی', followers: 125000, engagementRate: 4.2 },
  { id: 2, name: 'سارا احمدی', followers: 89000, engagementRate: 6.8 },
  { id: 3, name: 'علی محمدی', followers: 350000, engagementRate: 2.1 },
]

export function SortableTableExample() {
  const [sortColumn, setSortColumn] = useState<SortColumn>(null)
  const [sortDirection, setSortDirection] = useState<SortDirection>(null)

  function handleSort(column: SortColumn) {
    if (sortColumn === column) {
      setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc')
    } else {
      setSortColumn(column)
      setSortDirection('asc')
    }
  }

  const sorted = [...data].sort((a, b) => {
    if (!sortColumn || !sortDirection) return 0
    const dir = sortDirection === 'asc' ? 1 : -1
    if (sortColumn === 'name') return a.name.localeCompare(b.name, 'fa') * dir
    return (a[sortColumn] - b[sortColumn]) * dir
  })

  const getSortDir = (col: SortColumn) => (sortColumn === col ? (sortDirection ?? 'none') : 'none')

  return (
    <Table>
      <TableHeader>
        <TableRow>
          <TableHead sortDirection={getSortDir('name')}>
            <TableSortHeader sorted={sortColumn === 'name' ? sortDirection : false} onClick={() => handleSort('name')}>
              نام
            </TableSortHeader>
          </TableHead>
          <TableHead sortDirection={getSortDir('followers')}>
            <TableSortHeader
              sorted={sortColumn === 'followers' ? sortDirection : false}
              onClick={() => handleSort('followers')}
            >
              فالوورها
            </TableSortHeader>
          </TableHead>
          <TableHead sortDirection={getSortDir('engagementRate')}>
            <TableSortHeader
              sorted={sortColumn === 'engagementRate' ? sortDirection : false}
              onClick={() => handleSort('engagementRate')}
            >
              نرخ تعامل
            </TableSortHeader>
          </TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {sorted.map((row) => (
          <TableRow key={row.id}>
            <TableCell>{row.name}</TableCell>
            <TableCell>{row.followers.toLocaleString('fa-IR')}</TableCell>
            <TableCell>{row.engagementRate}٪</TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  )
}

نکات

  • sortDirection روی TableHead وضعیت aria-sort را تنظیم می‌کند
  • از getSortDir برای تعیین وضعیت هر ستون استفاده کنید
  • وقتی هیچ ستونی مرتب نشده، مقدار 'none' برمی‌گرداند