Sean Hello

Data Grid Table

Dashboards 12

About

Here is Data Grid Table component

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Data Grid Table to your project and fits it to your theme.

Code

How Data Grid Table is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

import { useEffect, useMemo, useState } from 'react';
import {
  Avatar,
  AvatarFallback,
  AvatarImage,
  AvatarIndicator,
  AvatarStatus,
  avatarStatusVariants,
} from '@/components/ui/avatar';
import { DataGrid, DataGridContainer } from '@/components/ui/data-grid-table';
import { DataGridPagination } from '@/components/ui/data-grid-table';
import {
  DataGridTable,
  DataGridTableRowSelect,
  DataGridTableRowSelectAll,
} from '@/components/ui/data-grid-table';
import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area';
import {
  ColumnDef,
  getCoreRowModel,
  getFilteredRowModel,
  getPaginationRowModel,
  getSortedRowModel,
  PaginationState,
  RowSelectionState,
  SortingState,
  useReactTable,
} from '@tanstack/react-table';

interface IData {
  id: string;
  name: string;
  availability: 'online' | 'away' | 'busy' | 'offline';
  avatar: string;
  status: 'active' | 'inactive';
  flag: string;
  email: string;
  company: string;
  role: string;
  joined: string;
  location: string;
  balance: number;
}

const demoData: IData[] = [
  {
    id: '1',
    name: 'Kathryn Campbell',
    availability: 'online',
    avatar: 'women/1.jpg',
    status: 'active',
    flag: '🇺🇸',
    email: '[email protected]',
    company: 'Apple',
    role: 'CEO',
    joined: '2021-04-15',
    location: 'San Francisco, USA',
    balance: 5143.03,
  },
  {
    id: '2',
    name: 'Robert Smith',
    availability: 'away',
    avatar: 'men/2.jpg',
    status: 'inactive',
    flag: '🇬🇧',
    email: '[email protected]',
    company: 'OpenAI',
    role: 'CTO',
    joined: '2020-07-20',
    location: 'London, UK',
    balance: 4321.87,
  },
  {
    id: '3',
    name: 'Sophia Johnson',
    availability: 'busy',
    avatar: 'women/3.jpg',
    status: 'active',
    flag: '🇨🇦',
    email: '[email protected]',
    company: 'Meta',
    role: 'Designer',
    joined: '2019-03-12',
    location: 'Toronto, Canada',
    balance: 7654.98,
  },
  {
    id: '4',
    name: 'Lucas Walker',
    availability: 'offline',
    avatar: 'men/4.jpg',
    status: 'inactive',
    flag: '🇦🇺',
    email: '[email protected]',
    company: 'Tesla',
    role: 'Developer',
    joined: '2022-01-18',
    location: 'Sydney, Australia',
    balance: 3456.45,
  },
  {
    id: '5',
    name: 'Emily Davis',
    availability: 'online',
    avatar: 'women/5.jpg',
    status: 'active',
    flag: '🇩🇪',
    email: '[email protected]',
    company: 'SAP',
    role: 'Lawyer',
    joined: '2023-05-23',
    location: 'Berlin, Germany',
    balance: 9876.54,
  },
  {
    id: '6',
    name: 'James Brown',
    availability: 'away',
    avatar: 'men/6.jpg',
    status: 'active',
    flag: '🇲🇾',
    email: '[email protected]',
    company: 'Keenthemes',
    role: 'Director',
    joined: '2018-11-30',
    location: 'Kuala Lumpur, MY',
    balance: 6214.22,
  },
  {
    id: '7',
    name: 'Isabella Martinez',
    availability: 'busy',
    avatar: 'women/7.jpg',
    status: 'inactive',
    flag: '🇪🇸',
    email: '[email protected]',
    company: 'BBVA',
    role: 'Product Manager',
    joined: '2021-06-14',
    location: 'Barcelona, Spain',
    balance: 5321.77,
  },
  {
    id: '8',
    name: 'Benjamin Harris',
    availability: 'offline',
    avatar: 'men/8.jpg',
    status: 'active',
    flag: '🇯🇵',
    email: '[email protected]',
    company: 'Sony',
    role: 'Marketing Lead',
    joined: '2020-10-22',
    location: 'Tokyo, Japan',
    balance: 8452.39,
  },
  {
    id: '9',
    name: 'Olivia Brown',
    availability: 'online',
    avatar: 'men/9.jpg',
    status: 'active',
    flag: '🇫🇷',
    email: '[email protected]',
    company: 'LVMH',
    role: 'Data Scientist',
    joined: '2019-09-17',
    location: 'Paris, France',
    balance: 7345.1,
  },
  {
    id: '10',
    name: 'Michael Clark',
    availability: 'away',
    avatar: 'women/10.jpg',
    status: 'inactive',
    flag: '🇮🇹',
    email: '[email protected]',
    company: 'ENI',
    role: 'Engineer',
    joined: '2023-02-11',
    location: 'Milan, Italy',
    balance: 5214.88,
  },
  {
    id: '11',
    name: 'Ava Wilson',
    availability: 'busy',
    avatar: 'women/11.jpg',
    status: 'active',
    flag: '🇧🇷',
    email: '[email protected]',
    company: 'Vale',
    role: 'Software Engineer',
    joined: '2022-12-01',
    location: 'Rio de Janeiro, Brazil',
    balance: 9421.5,
  },
  {
    id: '12',
    name: 'David Young',
    availability: 'offline',
    avatar: 'men/12.jpg',
    status: 'active',
    flag: '🇮🇳',
    email: '[email protected]',
    company: 'Tata',
    role: 'Sales Manager',
    joined: '2020-03-27',
    location: 'Mumbai, India',
    balance: 4521.67,
  },
];

export default function DataGridDemo() {
  const [pagination, setPagination] = useState<PaginationState>({
    pageIndex: 0,
    pageSize: 5,
  });
  const [sorting, setSorting] = useState<SortingState>([{ id: 'name', desc: true }]);
  const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const [selectedIds, setSelectedIds] = useState<string[]>([]);

  useEffect(() => {
    const selectedRowIds = Object.keys(rowSelection);
    if (selectedRowIds.length > 0) {
      setSelectedIds(selectedRowIds);
    } else {
      setSelectedIds([]);
    }
  }, [rowSelection]);

  const columns = useMemo<ColumnDef<IData>[]>(
    () => [
      {
        accessorKey: 'id',
        header: () => <DataGridTableRowSelectAll />,
        cell: ({ row }) => <DataGridTableRowSelect row={row} />,
        enableSorting: false,
        size: 35,
        meta: {
          headerClassName: '',
          cellClassName: '',
        },
      },
      {
        accessorKey: 'name',
        id: 'name',
        header: 'Name',
        cell: ({ row }) => {
          const availability = row.original.availability as keyof typeof avatarStatusVariants;

          return (
            <div className="flex items-center gap-3">
              <Avatar className="size-8">
                <AvatarImage src={`https://randomuser.me/api/portraits/${row.original.avatar}`} alt={row.original.name} />
                <AvatarFallback>N</AvatarFallback>
                <AvatarIndicator className="-end-2 -bottom-2">
                  <AvatarStatus variant={availability} className="size-2.5" />
                </AvatarIndicator>
              </Avatar>
              <div className="space-y-px">
                <div className="font-medium text-foreground">{row.original.name}</div>
                <div className="text-muted-foreground">{row.original.email}</div>
              </div>
            </div>
          );
        },
        size: 200,
        enableSorting: true,
        enableHiding: false,
      },
      {
        accessorKey: 'company',
        id: 'company',
        header: 'Role',
        cell: ({ row }) => {
          return (
            <div className="space-y-0.5">
              <div className="font-medium text-foreground">{row.original.role}</div>
              <div className="text-muted-foreground">{row.original.company}</div>
            </div>
          );
        },
        size: 140,
        enableSorting: true,
        enableHiding: false,
      },
      {
        accessorKey: 'location',
        header: 'Location',
        cell: ({ row }) => {
          return (
            <div className="flex items-center gap-1.5">
              {row.original.flag}
              <div className="font-medium text-foreground">{row.original.location}</div>
            </div>
          );
        },
        size: 180,
        meta: {
          headerClassName: '',
          cellClassName: 'text-start',
        },
      },
      {
        accessorKey: 'joined',
        header: 'Joined',
        cell: (info) => info.getValue() as string,
        size: 120,
        meta: {
          headerClassName: '',
          cellClassName: 'font-medium',
        },
      },
    ],
    [],
  );

  const table = useReactTable({
    columns,
    data: demoData,
    pageCount: Math.ceil((demoData?.length || 0) / pagination.pageSize),
    getRowId: (row: IData) => row.id,
    state: {
      pagination,
      sorting,
      rowSelection,
    },
    enableRowSelection: true,
    onRowSelectionChange: setRowSelection,
    onPaginationChange: setPagination,
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
  });

  return (
    <DataGrid table={table} recordCount={demoData?.length || 0}>
      <div className="w-full space-y-2.5 px-5">
        <DataGridContainer>
          <ScrollArea>
            <DataGridTable />
            <ScrollBar orientation="horizontal" />
          </ScrollArea>
        </DataGridContainer>
        <DataGridPagination />
      </div>
    </DataGrid>
  );
}

Dependencies

More by Sean Hello

View all
  • 3D Testimonails

    3D Testimonails

    3.4K
  • Line Charts 9

    Line Charts 9

    656
  • Alert

    Alert

    494
  • Line Charts 6

    Line Charts 6

    392
  • Area Charts 1

    Area Charts 1

    391
  • Scroll Area

    Scroll Area

    376
  • Navigation Menu

    Navigation Menu

    319
  • Area Charts 2

    Area Charts 2

    318

More in Dashboards

View all
  • Dashboard with Collapsible Sidebar

    Dashboard with Collapsible Sidebar

    2.5K
  • Sidebar

    Sidebar

    285
  • SaaS Template

    SaaS Template

    2.5K
  • Course Design Cards

    Course Design Cards

    1.1K
  • Chat template

    Chat template

    614
  • System Status Block

    System Status Block

    316
  • Statistics Card 7

    Statistics Card 7

    301
  • Bar Chart

    Bar Chart

    1