Skip to content

SimpleSortableTable

Lightweight table component built on TanStack Table for simple sortable tables.

Import

tsx
import { SimpleSortableTable } from '@/shared/ui/components/table/SimpleSortableTable'
import { type ColumnDef } from '@tanstack/react-table'

Props

SimpleSortableTableProps<T>

PropTypeDefaultDescription
Core
columnsColumnDef<T>[]RequiredTanStack Table column definitions
dataT[]RequiredArray of data objects
Sorting
initialSortSortingState[]Initial sorting state
Styling
density'compact' | 'normal' | 'spacious''normal'Row height density
classNamestring-Additional CSS classes
Row Interaction
onRowClick(row: T) => void-Row click handler
selectedRowIdstring-ID of currently selected row (for highlighting)
getRowId(row: T) => string-Custom row ID function
Expansion
expandablebooleanfalseEnable row expansion
renderExpandedRow(row: T, toggleExpand: () => void) => ReactNode-Render function for expanded content
expandedRowIdsstring[]-Controlled expanded row IDs
onExpandedChange(ids: string[]) => void-Callback when expanded rows change
multiExpandbooleantrueAllow multiple rows to be expanded simultaneously
defaultExpandedRowIdsstring[][]Initially expanded row IDs
Pagination
enablePaginationbooleanfalseEnable pagination
defaultPageSizenumber10Default page size
pageSizeOptionsnumber[][5, 10, 20, 50]Page size options

Column Definition

Uses standard TanStack Table ColumnDef<T>:

ts
interface ColumnDef<T> {
  id?: string
  accessorKey?: keyof T
  accessorFn?: (row: T) => unknown
  header?: string | ((props: HeaderContext<T>) => ReactNode)
  cell?: (props: CellContext<T>) => ReactNode
  enableSorting?: boolean
  enableHiding?: boolean
  size?: number
  minSize?: number
  maxSize?: number
}

Examples

Basic Sortable Table

tsx
import { SimpleSortableTable } from '@/shared/ui/components/table/SimpleSortableTable'
import { type ColumnDef } from '@tanstack/react-table'

type Task = {
  id: string
  title: string
  priority: number
  status: string
}

const columns: ColumnDef<Task>[] = [
  {
    accessorKey: 'title',
    header: 'Task Title',
  },
  {
    accessorKey: 'priority',
    header: 'Priority',
    enableSorting: true,
  },
  {
    accessorKey: 'status',
    header: 'Status',
  },
]

function TaskList({ tasks }: { tasks: Task[] }) {
  return (
    <SimpleSortableTable
      columns={columns}
      data={tasks}
      initialSort={[{ id: 'priority', desc: true }]}
    />
  )
}

With Row Click

tsx
function ClickableTable() {
  const navigate = useNavigate()

  return (
    <SimpleSortableTable
      columns={columns}
      data={tasks}
      onRowClick={(task) => navigate(`/tasks/${task.id}`)}
      selectedRowId={currentTaskId}
    />
  )
}

With Expansion

tsx
function ExpandableTable() {
  return (
    <SimpleSortableTable
      columns={columns}
      data={tasks}
      expandable
      renderExpandedRow={(task, toggleExpand) => (
        <div className="p-4 bg-muted/50">
          <h4 className="font-semibold mb-2">Task Details</h4>
          <p>{task.description}</p>
          <Button onClick={toggleExpand}>Close</Button>
        </div>
      )}
      multiExpand={false}
    />
  )
}

With Pagination

tsx
function PaginatedTable() {
  return (
    <SimpleSortableTable
      columns={columns}
      data={tasks}
      enablePagination
      defaultPageSize={20}
      pageSizeOptions={[10, 20, 50]}
    />
  )
}

Controlled Expansion

tsx
function ControlledExpansion() {
  const [expandedIds, setExpandedIds] = useState<string[]>([])

  return (
    <>
      <Button onClick={() => setExpandedIds([])}>
        Collapse All
      </Button>
      
      <SimpleSortableTable
        columns={columns}
        data={tasks}
        expandable
        renderExpandedRow={(task) => <TaskDetails task={task} />}
        expandedRowIds={expandedIds}
        onExpandedChange={setExpandedIds}
      />
    </>
  )
}

Density Variants

tsx
// Compact - minimal padding
<SimpleSortableTable density="compact" {...props} />

// Normal - balanced (default)
<SimpleSortableTable density="normal" {...props} />

// Spacious - generous padding
<SimpleSortableTable density="spacious" {...props} />

When to Use

Use SimpleSortableTable when:

  • You need client-side sorting only
  • No filtering or pagination required (or simple pagination)
  • Working with TanStack Table column definitions
  • Simpler API is preferred
  • Dataset is small to medium (< 1000 rows)

Use DataTable instead when:

  • You need server-side processing
  • Column filters are required
  • Advanced features needed (CSV export, column visibility, etc.)
  • State persistence is important
  • Working with large datasets

See Also