---
sidebar_position: 3
sidebar_class_name: hidden
---

import Paper from "@site/src/components/paper";
import TableDefault, { TableModern, TableElegant, TableMinimal } from "@site/src/components/table";

# Rc Table

React table component with useful functions.

<div className="mb-16" />

## Installation

<hr />

1.  Install the **rc-table** package.

<div className="mb-4" />

```bash
npm i rc-table
```

<div className="mb-4" />

2. Create a table component, **components/table.tsx**

<div className="mb-4" />

```ts
import React from "react";
import Table from "rc-table";
import { Empty, cn } from "rizzui";

export type ExtractProps<T> = T extends React.ComponentType<infer P> ? P : T;

const tableStyles = {
  table:
    "[&_.rc-table-content]:overflow-x-auto [&_table]:w-full [&_.rc-table-row:hover]:bg-muted/60",
  thead:
    "[&_thead]:text-left [&_thead]:rtl:text-right [&_th.rc-table-cell]:uppercase [&_th.rc-table-cell]:text-xs [&_th.rc-table-cell]:font-medium [&_th.rc-table-cell]:tracking-wide",
  tCell:
    "[&_.rc-table-cell]:px-3 [&_th.rc-table-cell]:py-3 [&_td.rc-table-cell]:py-4",
  variants: {
    classic:
      "[&_thead]:bg-muted/50 [&_.rc-table-container]:border-x [&_.rc-table-container]:border-muted [&_td.rc-table-cell]:border-b [&_td.rc-table-cell]:border-muted [&_thead]:border-y [&_thead]:border-muted",
    modern:
      "[&_thead]:bg-muted/50 [&_td.rc-table-cell]:border-b [&_td.rc-table-cell]:border-muted",
    minimal: "[&_thead]:bg-muted/50",
    elegant:
      "[&_thead]:border-y [&_thead]:border-muted [&_td.rc-table-cell]:border-b [&_td.rc-table-cell]:border-muted",
  },
  striped: "[&_.rc-table-row:nth-child(2n)_.rc-table-cell]:bg-muted/40",
};

type RCTableProps = ExtractProps<typeof Table>;

export interface TableProps
  extends Omit<RCTableProps, "className" | "emptyText"> {
  emptyText?: React.ReactElement;
  variant?: keyof typeof tableStyles.variants;
  striped?: boolean;
  className?: string;
}

export default function RcTable({
  striped,
  variant = "classic",
  emptyText,
  className,
  ...props
}: TableProps) {
  return (
    <Table
      className={cn(
        tableStyles.table,
        tableStyles.thead,
        tableStyles.tCell,
        tableStyles.variants[variant],
        striped && tableStyles.striped,
        className
      )}
      emptyText={emptyText ?? <Empty />}
      {...props}
    />
  );
}

RcTable.displayName = "Table";
```

3. You need to create one more component for the table header cell

<div className="mb-4" />

```ts
import React from "react";
import { cn } from "rizzui";

type TextAlign = "left" | "center" | "right";

export interface HeaderCellProps {
  title: React.ReactNode;
  width?: number;
  align?: TextAlign;
  ellipsis?: boolean;
  sortable?: boolean;
  ascending?: boolean;
  iconClassName?: string;
  className?: string;
}

function handleTextAlignment(align: TextAlign) {
  if (align === "center") return "justify-center";
  if (align === "right") return "justify-end rtl:justify-start";
  return "";
}

export default function HeaderCell({
  title,
  align = "left",
  width,
  ellipsis,
  sortable,
  ascending,
  iconClassName,
  className,
}: HeaderCellProps) {
  if (ellipsis && width === undefined) {
    console.warn(
      "When ellipsis is true make sure you are using the same column width in HeaderCell component too."
    );
  }

  if (width !== undefined && ellipsis !== true) {
    console.warn(
      "width prop without ellipsis won't work, please set ellipsis prop true."
    );
  }

  return (
    <div
      className={cn(
        "flex items-center gap-1",
        sortable && "cursor-pointer",
        handleTextAlignment(align),
        className
      )}
    >
      <div
        {...(ellipsis && { className: "truncate" })}
        {...(ellipsis && width && { style: { width } })}
      >
        {title}
      </div>

      {sortable && (
        <div className="inline-flex">
          {ascending ? (
            <svg
              xmlns="http://www.w3.org/2000/svg"
              fill="currentColor"
              className={cn("h-auto w-3", iconClassName)}
              viewBox="0 0 16 16"
            >
              <path d="m7.247 4.86-4.796 5.481c-.566.647-.106 1.659.753 1.659h9.592a1 1 0 0 0 .753-1.659l-4.796-5.48a1 1 0 0 0-1.506 0z" />
            </svg>
          ) : (
            <svg
              xmlns="http://www.w3.org/2000/svg"
              fill="currentColor"
              className={cn("h-auto w-3", iconClassName)}
              viewBox="0 0 16 16"
            >
              <path d="M7.247 11.14 2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z" />
            </svg>
          )}
        </div>
      )}
    </div>
  );
}

HeaderCell.displayName = "HeaderCell";
```

<div className="mb-20 md:mb-28" />

## Default

The default style of **Table** component.

<Paper className="block">
  <TableDefault />
</Paper>

```tsx
import React from "react";
import Table from "@components/table";
import HeaderCell from "@components/header-cell";
import { Checkbox, Avatar, Text, Badge } from "rizzui";

const initialData = [
  {
    id: "1",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/1.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "2",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/2.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "3",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/3.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "4",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/4.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "5",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/5.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "6",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/6.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
];

function getStatusBadge(status: string) {
  switch (status.toLowerCase()) {
    case "pending":
      return <Badge variant="flat">{status}</Badge>;
    case "active":
      return (
        <Badge
          variant="flat"
          color="success"
        >
          {status}
        </Badge>
      );
    case "warning":
      return (
        <Badge
          variant="flat"
          color="warning"
        >
          {status}
        </Badge>
      );
    case "danger":
      return (
        <Badge
          variant="flat"
          color="danger"
        >
          {status}
        </Badge>
      );
    default:
      return null;
  }
}

const getColumns = (order: string, column: string, onHeaderClick: (value: string) => any) => [
  {
    title: <></>,
    dataIndex: "checked",
    key: "checked",
    width: 50,
    render: () => (
      <div className="inline-flex cursor-pointer">
        <Checkbox variant="flat" />
      </div>
    ),
  },
  {
    title: (
      <HeaderCell
        title="Id"
        sortable
        ascending={order === "asc" && column === "id"}
      />
    ),
    onHeaderCell: () => onHeaderClick("id"),
    dataIndex: "id",
    key: "id",
    width: 50,
  },
  {
    title: <HeaderCell title="Employee" />,
    dataIndex: "employee",
    key: "employee",
    width: 250,
    render: (employee: any) => (
      <div className="flex items-center">
        <Avatar
          name="John Doe"
          src={employee.avatar}
        />
        <div className="ml-3 rtl:ml-0 rtl:mr-3">
          <Text
            as="h6"
            className="mb-0.5 !text-sm font-medium"
          >
            {employee.name}
          </Text>
          <Text
            as="p"
            className="text-xs text-gray-400"
          >
            {employee.userName}
          </Text>
        </div>
      </div>
    ),
  },
  {
    title: <HeaderCell title="Designation" />,
    dataIndex: "designation",
    key: "designation",
    width: 320,
    render: (designation: any) => (
      <div>
        <Text
          as="h6"
          className="mb-0.5 !text-sm font-medium"
        >
          {designation.role}
        </Text>
        <Text
          as="p"
          className="text-xs text-gray-400"
        >
          {designation.company}
        </Text>
      </div>
    ),
  },
  {
    title: <HeaderCell title="Phone Number" />,
    dataIndex: "phoneNumber",
    key: "phoneNumber",
    width: 200,
  },
  {
    title: <HeaderCell title="Email" />,
    dataIndex: "email",
    key: "email",
    width: 200,
  },
  {
    title: <HeaderCell title="Status" />,
    dataIndex: "status",
    key: "status",
    width: 120,
    render: (value: string) => getStatusBadge(value),
  },
  {
    title: <></>,
    dataIndex: "action",
    key: "action",
    width: 120,
    render: (_: string, row: any) => (
      <div className="flex items-center gap-2">
        <button
          type="button"
          className="text-primary underline"
          onClick={() => alert(`Edit item #${row.id}`)}
        >
          Edit
        </button>
        <button
          type="button"
          className="underline"
        >
          View
        </button>
      </div>
    ),
  },
];

export default function App() {
  const [order, setOrder] = React.useState<string>("desc");
  const [column, setColumn] = React.useState<string>("");
  const [data, setData] = React.useState<typeof initialData>(initialData);
  const onHeaderClick = (value: string) => ({
    onClick: () => {
      setColumn(value);
      setOrder(order === "desc" ? "asc" : "desc");
      if (order === "desc") {
        // @ts-ignore
        setData([...data.sort((a, b) => (a[value] > b[value] ? -1 : 1))]);
      } else {
        // @ts-ignore
        setData([...data.sort((a, b) => (a[value] > b[value] ? 1 : -1))]);
      }
    },
  });
  const columns: any = React.useMemo(
    () => getColumns(order, column, onHeaderClick),
    [order, column, onHeaderClick]
  );

  return (
    <Table
      data={data}
      columns={columns}
      className="text-sm"
    />
  );
}
```

<div className="mb-16" />

## Modern

You can change the style of **Table** by changing property [**variant**](#table-variants).

<Paper className="block">
  <TableModern />
</Paper>

```tsx
import React from "react";
import Table from "@components/table";
import HeaderCell from "@components/header-cell";
import { Checkbox, Avatar, Text, Badge } from "rizzui";

const initialData = [
  {
    id: "1",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/1.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "2",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/2.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "3",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/3.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "4",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/4.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "5",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/5.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "6",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/6.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
];

function getStatusBadge(status: string) {
  switch (status.toLowerCase()) {
    case "pending":
      return <Badge variant="flat">{status}</Badge>;
    case "active":
      return (
        <Badge
          variant="flat"
          color="success"
        >
          {status}
        </Badge>
      );
    case "warning":
      return (
        <Badge
          variant="flat"
          color="warning"
        >
          {status}
        </Badge>
      );
    case "danger":
      return (
        <Badge
          variant="flat"
          color="danger"
        >
          {status}
        </Badge>
      );
    default:
      return null;
  }
}

const getColumns = (order: string, column: string, onHeaderClick: (value: string) => any) => [
  {
    title: <></>,
    dataIndex: "checked",
    key: "checked",
    width: 50,
    render: () => (
      <div className="inline-flex cursor-pointer">
        <Checkbox variant="flat" />
      </div>
    ),
  },
  {
    title: (
      <HeaderCell
        title="Id"
        sortable
        ascending={order === "asc" && column === "id"}
      />
    ),
    onHeaderCell: () => onHeaderClick("id"),
    dataIndex: "id",
    key: "id",
    width: 50,
  },
  {
    title: <HeaderCell title="Employee" />,
    dataIndex: "employee",
    key: "employee",
    width: 250,
    render: (employee: any) => (
      <div className="flex items-center">
        <Avatar
          name="John Doe"
          src={employee.avatar}
        />
        <div className="ml-3 rtl:ml-0 rtl:mr-3">
          <Text
            as="h6"
            className="mb-0.5 !text-sm font-medium"
          >
            {employee.name}
          </Text>
          <Text
            as="p"
            className="text-xs text-gray-400"
          >
            {employee.userName}
          </Text>
        </div>
      </div>
    ),
  },
  {
    title: <HeaderCell title="Designation" />,
    dataIndex: "designation",
    key: "designation",
    width: 320,
    render: (designation: any) => (
      <div>
        <Text
          as="h6"
          className="mb-0.5 !text-sm font-medium"
        >
          {designation.role}
        </Text>
        <Text
          as="p"
          className="text-xs text-gray-400"
        >
          {designation.company}
        </Text>
      </div>
    ),
  },
  {
    title: <HeaderCell title="Phone Number" />,
    dataIndex: "phoneNumber",
    key: "phoneNumber",
    width: 200,
  },
  {
    title: <HeaderCell title="Email" />,
    dataIndex: "email",
    key: "email",
    width: 200,
  },
  {
    title: <HeaderCell title="Status" />,
    dataIndex: "status",
    key: "status",
    width: 120,
    render: (value: string) => getStatusBadge(value),
  },
  {
    title: <></>,
    dataIndex: "action",
    key: "action",
    width: 120,
    render: (_: string, row: any) => (
      <div className="flex items-center gap-2">
        <button
          type="button"
          className="text-primary underline"
          onClick={() => alert(`Edit item #${row.id}`)}
        >
          Edit
        </button>
        <button
          type="button"
          className="underline"
        >
          View
        </button>
      </div>
    ),
  },
];

export default function App() {
  const [order, setOrder] = React.useState<string>("desc");
  const [column, setColumn] = React.useState<string>("");
  const [data, setData] = React.useState<typeof initialData>(initialData);
  const onHeaderClick = (value: string) => ({
    onClick: () => {
      setColumn(value);
      setOrder(order === "desc" ? "asc" : "desc");
      if (order === "desc") {
        // @ts-ignore
        setData([...data.sort((a, b) => (a[value] > b[value] ? -1 : 1))]);
      } else {
        // @ts-ignore
        setData([...data.sort((a, b) => (a[value] > b[value] ? 1 : -1))]);
      }
    },
  });
  const columns: any = React.useMemo(
    () => getColumns(order, column, onHeaderClick),
    [order, column, onHeaderClick]
  );

  return (
    <Table
      data={data}
      columns={columns}
      className="text-sm"
      variant="modern"
    />
  );
}
```

<div className="mb-16" />

## Elegant

You can change the style of **Table** by changing property [**variant**](#table-variants).

<Paper className="block">
  <TableElegant />
</Paper>

```tsx
import React from "react";
import Table from "@components/table";
import HeaderCell from "@components/header-cell";
import { Checkbox, Avatar, Text, Badge } from "rizzui";

const initialData = [
  {
    id: "1",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/1.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "2",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/2.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "3",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/3.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "4",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/4.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "5",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/5.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "6",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/6.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
];

function getStatusBadge(status: string) {
  switch (status.toLowerCase()) {
    case "pending":
      return <Badge variant="flat">{status}</Badge>;
    case "active":
      return (
        <Badge
          variant="flat"
          color="success"
        >
          {status}
        </Badge>
      );
    case "warning":
      return (
        <Badge
          variant="flat"
          color="warning"
        >
          {status}
        </Badge>
      );
    case "danger":
      return (
        <Badge
          variant="flat"
          color="danger"
        >
          {status}
        </Badge>
      );
    default:
      return null;
  }
}

const getColumns = (order: string, column: string, onHeaderClick: (value: string) => any) => [
  {
    title: <></>,
    dataIndex: "checked",
    key: "checked",
    width: 50,
    render: () => (
      <div className="inline-flex cursor-pointer">
        <Checkbox variant="flat" />
      </div>
    ),
  },
  {
    title: (
      <HeaderCell
        title="Id"
        sortable
        ascending={order === "asc" && column === "id"}
      />
    ),
    onHeaderCell: () => onHeaderClick("id"),
    dataIndex: "id",
    key: "id",
    width: 50,
  },
  {
    title: <HeaderCell title="Employee" />,
    dataIndex: "employee",
    key: "employee",
    width: 250,
    render: (employee: any) => (
      <div className="flex items-center">
        <Avatar
          name="John Doe"
          src={employee.avatar}
        />
        <div className="ml-3 rtl:ml-0 rtl:mr-3">
          <Text
            as="h6"
            className="mb-0.5 !text-sm font-medium"
          >
            {employee.name}
          </Text>
          <Text
            as="p"
            className="text-xs text-gray-400"
          >
            {employee.userName}
          </Text>
        </div>
      </div>
    ),
  },
  {
    title: <HeaderCell title="Designation" />,
    dataIndex: "designation",
    key: "designation",
    width: 320,
    render: (designation: any) => (
      <div>
        <Text
          as="h6"
          className="mb-0.5 !text-sm font-medium"
        >
          {designation.role}
        </Text>
        <Text
          as="p"
          className="text-xs text-gray-400"
        >
          {designation.company}
        </Text>
      </div>
    ),
  },
  {
    title: <HeaderCell title="Phone Number" />,
    dataIndex: "phoneNumber",
    key: "phoneNumber",
    width: 200,
  },
  {
    title: <HeaderCell title="Email" />,
    dataIndex: "email",
    key: "email",
    width: 200,
  },
  {
    title: <HeaderCell title="Status" />,
    dataIndex: "status",
    key: "status",
    width: 120,
    render: (value: string) => getStatusBadge(value),
  },
  {
    title: <></>,
    dataIndex: "action",
    key: "action",
    width: 120,
    render: (_: string, row: any) => (
      <div className="flex items-center gap-2">
        <button
          type="button"
          className="text-primary underline"
          onClick={() => alert(`Edit item #${row.id}`)}
        >
          Edit
        </button>
        <button
          type="button"
          className="underline"
        >
          View
        </button>
      </div>
    ),
  },
];

export default function App() {
  const [order, setOrder] = React.useState<string>("desc");
  const [column, setColumn] = React.useState<string>("");
  const [data, setData] = React.useState<typeof initialData>(initialData);
  const onHeaderClick = (value: string) => ({
    onClick: () => {
      setColumn(value);
      setOrder(order === "desc" ? "asc" : "desc");
      if (order === "desc") {
        // @ts-ignore
        setData([...data.sort((a, b) => (a[value] > b[value] ? -1 : 1))]);
      } else {
        // @ts-ignore
        setData([...data.sort((a, b) => (a[value] > b[value] ? 1 : -1))]);
      }
    },
  });
  const columns: any = React.useMemo(
    () => getColumns(order, column, onHeaderClick),
    [order, column, onHeaderClick]
  );

  return (
    <Table
      data={data}
      columns={columns}
      className="text-sm"
      variant="elegant"
    />
  );
}
```

<div className="mb-16" />

## Minimal

You can change the style of **Table** by changing property [**variant**](#table-variants).

<Paper className="block">
  <TableMinimal />
</Paper>

```tsx
import React from "react";
import Table from "@components/table";
import HeaderCell from "@components/header-cell";
import { Checkbox, Avatar, Text, Badge } from "rizzui";

const initialData = [
  {
    id: "1",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/1.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "2",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/2.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "3",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/3.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "4",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/4.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "5",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/5.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
  {
    id: "6",
    employee: {
      name: "Jon Brown",
      userName: "@fredchaparro",
      avatar: "https://randomuser.me/api/portraits/men/6.jpg",
    },
    designation: {
      role: "Front-End Developer",
      company: "REDQ",
    },
    phoneNumber: "+880136987584",
    email: "jhondoe@aegonui.com",
    status: "Active",
  },
];

function getStatusBadge(status: string) {
  switch (status.toLowerCase()) {
    case "pending":
      return <Badge variant="flat">{status}</Badge>;
    case "active":
      return (
        <Badge
          variant="flat"
          color="success"
        >
          {status}
        </Badge>
      );
    case "warning":
      return (
        <Badge
          variant="flat"
          color="warning"
        >
          {status}
        </Badge>
      );
    case "danger":
      return (
        <Badge
          variant="flat"
          color="danger"
        >
          {status}
        </Badge>
      );
    default:
      return null;
  }
}

const getColumns = (order: string, column: string, onHeaderClick: (value: string) => any) => [
  {
    title: <></>,
    dataIndex: "checked",
    key: "checked",
    width: 50,
    render: () => (
      <div className="inline-flex cursor-pointer">
        <Checkbox variant="flat" />
      </div>
    ),
  },
  {
    title: (
      <HeaderCell
        title="Id"
        sortable
        ascending={order === "asc" && column === "id"}
      />
    ),
    onHeaderCell: () => onHeaderClick("id"),
    dataIndex: "id",
    key: "id",
    width: 50,
  },
  {
    title: <HeaderCell title="Employee" />,
    dataIndex: "employee",
    key: "employee",
    width: 250,
    render: (employee: any) => (
      <div className="flex items-center">
        <Avatar
          name="John Doe"
          src={employee.avatar}
        />
        <div className="ml-3 rtl:ml-0 rtl:mr-3">
          <Text
            as="h6"
            className="mb-0.5 !text-sm font-medium"
          >
            {employee.name}
          </Text>
          <Text
            as="p"
            className="text-xs text-gray-400"
          >
            {employee.userName}
          </Text>
        </div>
      </div>
    ),
  },
  {
    title: <HeaderCell title="Designation" />,
    dataIndex: "designation",
    key: "designation",
    width: 320,
    render: (designation: any) => (
      <div>
        <Text
          as="h6"
          className="mb-0.5 !text-sm font-medium"
        >
          {designation.role}
        </Text>
        <Text
          as="p"
          className="text-xs text-gray-400"
        >
          {designation.company}
        </Text>
      </div>
    ),
  },
  {
    title: <HeaderCell title="Phone Number" />,
    dataIndex: "phoneNumber",
    key: "phoneNumber",
    width: 200,
  },
  {
    title: <HeaderCell title="Email" />,
    dataIndex: "email",
    key: "email",
    width: 200,
  },
  {
    title: <HeaderCell title="Status" />,
    dataIndex: "status",
    key: "status",
    width: 120,
    render: (value: string) => getStatusBadge(value),
  },
  {
    title: <></>,
    dataIndex: "action",
    key: "action",
    width: 120,
    render: (_: string, row: any) => (
      <div className="flex items-center gap-2">
        <button
          type="button"
          className="text-primary underline"
          onClick={() => alert(`Edit item #${row.id}`)}
        >
          Edit
        </button>
        <button
          type="button"
          className="underline"
        >
          View
        </button>
      </div>
    ),
  },
];

export default function App() {
  const [order, setOrder] = React.useState<string>("desc");
  const [column, setColumn] = React.useState<string>("");
  const [data, setData] = React.useState<typeof initialData>(initialData);
  const onHeaderClick = (value: string) => ({
    onClick: () => {
      setColumn(value);
      setOrder(order === "desc" ? "asc" : "desc");
      if (order === "desc") {
        // @ts-ignore
        setData([...data.sort((a, b) => (a[value] > b[value] ? -1 : 1))]);
      } else {
        // @ts-ignore
        setData([...data.sort((a, b) => (a[value] > b[value] ? 1 : -1))]);
      }
    },
  });
  const columns: any = React.useMemo(
    () => getColumns(order, column, onHeaderClick),
    [order, column, onHeaderClick]
  );

  return (
    <Table
      data={data}
      columns={columns}
      className="text-sm"
      variant="minimal"
    />
  );
}
```

<div className="mb-20" />

## API Reference

<hr />

<div className="mb-10" />

### Table Props

Here is the API documentation of the Table component.

<div className="overflow-x-auto">

|         Props          |                             Type                              |                        Description                         |   Default   |
| :--------------------: | :-----------------------------------------------------------: | :--------------------------------------------------------: | :---------: |
|       emptyText        |                          `ReactNode`                          | Set empty text, it will only appear when table has no data |    \_\_     |
|        variant         |               [TableVariants](#table-variants)                |             The variants of the component are:             | `"classic"` |
|        striped         |                           `boolean`                           |                     Add striping style                     |    \_\_     |
|       className        |                           `string`                            |             Add custom classes for extra style             |    \_\_     |
|           id           |                           `string`                            |                                                            |    \_\_     |
|         style          |                        `CSSProperties`                        |                                                            |    \_\_     |
|         title          |               `PanelRender<DefaultRecordType>`                |                                                            |    \_\_     |
|        caption         |                          `ReactNode`                          |                                                            |    \_\_     |
|          data          |                `readonly DefaultRecordType[]`                 |                                                            |    \_\_     |
|         footer         |               `PanelRender<DefaultRecordType>`                |                                                            |    \_\_     |
|        summary         |     `((data: readonly DefaultRecordType[]) => ReactNode)`     |                                                            |    \_\_     |
|       prefixCls        |                           `string`                            |                                                            |    \_\_     |
|       direction        |                          `ltr` `rtl`                          |                                                            |    \_\_     |
|    expandedRowKeys     |                            `Key[]`                            |                                                            |    \_\_     |
| defaultExpandedRowKeys |                            `key[]`                            |                                                            |    \_\_     |
|   expandedRowRender    |            `ExpandedRowRender<DefaultRecordType>`             |                                                            |    \_\_     |
|    expandRowByClick    |                           `boolean`                           |                                                            |    \_\_     |
|       expandIcon       |             `RenderExpandIcon<DefaultRecordType>`             |                                                            |    \_\_     |
|        onExpand        |  `((expanded: boolean, record: DefaultRecordType) => void)`   |                                                            |    \_\_     |
|  onExpandedRowsChange  |               `((expandedKeys: Key[]) => void)`               |                                                            |    \_\_     |
|  defaultExpandAllRows  |                           `boolean`                           |                                                            |    \_\_     |
|       indentSize       |                           `number`                            |                                                            |    \_\_     |
| expandIconColumnIndex  |                           `number`                            |                                                            |    \_\_     |
|  expandedRowClassName  |               `RowClassName<DefaultRecordType>`               |                                                            |    \_\_     |
|   childrenColumnName   |                           `string`                            |                                                            |    \_\_     |
|        columns         |               `ColumnsType<DefaultRecordType>`                |                                                            |    \_\_     |
|         rowKey         |            `string` `GetRowKey<DefaultRecordType>`            |                                                            |    \_\_     |
|      tableLayout       |                        `fixed` `auto`                         |                                                            |    \_\_     |
|         scroll         |                 [TableScroll](#table-scroll)                  |                                                            |    \_\_     |
|       expandable       |             `ExpandableConfig<DefaultRecordType>`             |                     Config expand rows                     |    \_\_     |
|      rowClassName      |          `string` `RowClassName<DefaultRecordType>`           |                                                            |    \_\_     |
|       showHeader       |                           `boolean`                           |                                                            |    \_\_     |
|       components       |             `TableComponents<DefaultRecordType>`              |                                                            |    \_\_     |
|         onRow          |            `GetComponentProps<DefaultRecordType>`             |                                                            |    \_\_     |
|      onHeaderRow       | `GetComponentProps<readonly ColumnType<DefaultRecordType>[]>` |                                                            |    \_\_     |
|     internalHooks      |                           `string`                            |                                                            |    \_\_     |
|    transformColumns    |       [TableTransformColumns](#table-transform-columns)       |                                                            |    \_\_     |
|      internalRefs      |         `{ body: MutableRefObject<HTMLDivElement>; }`         |                                                            |    \_\_     |
|         sticky         |                    `sticky` `tableSticky`                     |                                                            |    \_\_     |

</div>

- **Note:** You can check [**rc-table documentation**](https://www.npmjs.com/package/rc-table) for more details.

<div className="mb-10" />

### Table Variants

```ts
type TableVariants = "classic" | "modern" | "minimal" | "elegant";
```

<div className="mb-10" />

### Table Scroll

```ts
type TableScroll = { x?: string | number | true; y?: string | number } | undefined;
```

<div className="mb-10" />

### Table Transform Columns

```ts
type TableTransformColumns = (
  columns: ColumnsType<DefaultRecordType>
) => ColumnsType<DefaultRecordType>;
```
