Simple yet powerful react table component
Tags: react, table, gadwal, frontend
Published: 2024-07-13 17:46:59

## Simple yet Powerful React Table Component

In the ever-evolving landscape of front-end development, having efficient and customizable components is crucial for building robust applications. Today, I'm excited to introduce "Gadwal," a simple yet powerful React table component that can enhance your data presentation effortlessly.

### Features
Gadwal stands out with the following features:

- Customizable Columns: Define the structure and content of your table with ease.
- Custom Rendering for Each Cell: Tailor the display of data in each cell to suit your needs.
- Tailwind CSS Support: Seamlessly integrate with Tailwind CSS for consistent styling.
- open source


## Usage

```tsx
import React from 'react';
import Table from 'gadwal';

const data = [
  {
    id: 1,
    name: "Leanne Graham",
    username: "Bret",
    email: "oqkz9@example.com",
    website: "hildegard.org",
    phone: "1-770-736-8031 x56442",
    company: {
      name: "Romaguera-Crona",
      catchPhrase: "Multi-layered client-server neural-net",
      bs: "harness real-time e-markets",
    },
  }
];

const table = [
  { header: "id", name: "id", size: 2 },
  { header: "name", name: "name", size: 5 },
  { header: "email", name: "email", size: 5 },
  { header: "website", name: "website", size: 4 },
  { header: "phone", name: "phone", size: 4 },
  { header: "company", name: "company", size: 4, custom: (d) => d.company.name },
];

function App() {
  return (
    <div className="flex w-full">
      <Table data={data} table={table} />
    </div>
  );
}

export default App;
```
## output

![output of the table component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lt525y0mwmc3flnd26l9.png)

## it can do more complex tables

```tsx
import Table, { GadwalRow } from 'gadwal';
import { teammates, TeamMatesSchema } from './data.test';
import { _date } from '@helpers/date.helpers';


const userStatus = {
    "invited" : <div className='text-[#063EF8] bg-[#063EF8]/10 w-fit px-3 py-1 rounded-md  '> invited</div> ,
    "active" : <div className='text-[#00A774] bg-[#00A774]/10 w-fit px-3 py-1 rounded-md  '> active</div> ,
    "inactive" : <div className='text-[#A70027] bg-[#A70027]/10 w-fit px-3 py-1 rounded-md  '> inactive</div>
}

export default function Test() {

    const table: GadwalRow<TeamMatesSchema>[] = [
        { header : "email" , name : "email" , size : 7, custom : d =>{
            return <div className='flex items-center'>
                <div className="w-[50px] h-[50px] rounded-full  overflow-hidden mr-2">
                    <img src="https://images.pexels.com/photos/220453/pexels-photo-220453.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" alt="profile" className="w-full h-full rounded-full object-cover" />
                </div>
                <div className="flex-1">
                    <p className="capitalize mb-0 text-black">abdelrahman seada</p>
                    <p className="capitalize mb-0">{d.email}</p>
                </div>

            </div>
        } },
        { header : "status" , name : "status" , size : 4 , custom : d => userStatus[d.status] }, 
        { header : "role" , name :"type" , size : 4 , custom : d => <span className='capitalize'>{d.type.split(":")[1]}</span> },
        { header : "invited date" , name : "updated_at" , size : 4 , custom : d => _date(d.updated_at).local() }
    ];

  return (
   <Table
        data={teammates} 
        table={table}
        bodyProps={{ className : "border-b-[1px] items-center h-[90px] !p-0"  }}
        headerProps={{ className : "border-b-[1px] items-center cap   h-[90px]"  }}
        fixedHeight={false}
    />
  )
}
```
### output table 

![test table output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pvv20x1v5whdua07kl3u.png)

## typescript support
if we have an interface of our data like the following 
```ts
export interface TeamMatesSchema {
    status: "invited" | "active" | "inactive";
    user_name: string;
    _id: string;
    type: string;
    email: string;
    updated_at: string;
}

```
using Generic GadwalRow will help you to know what is the data looks like in the name key (which should match the data key between table and api data to display it)

```ts
GadwalRow<TeamMatesSchema>[]
```


![ts name support](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xo8i4ckmexxwvtmsjp3h.png)

also for custom cell rendering 

![custom cell rendering ts support](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0lpnrql6nzaffmkwxek.png)


## props

| props             | usage                                                              |required   | default |
| ----------------- | ------------------------------------------------------------------ | --------- |---------|
| data | table data that is going to be rendred| true | -|
| table | coulums of the table each represents a cell | true| - |
| fixedHeight | to force each table row to a fixed height (50px) | false | true |
| animated | animate table content | false | false |
| stripped  | make table rows stripped  | false | true |
| bodyProps | to pass custom styles , classes , ...etc all div attributes to each row of data | false | {} |
| headerProps | to pass custom styles , classes , ...etc all div attributes to only table head  | false | {} |
| bodyCellProps | to pass custom styles , classes , ...etc all div attributes to each row cells of data | false | {} |
| headerCellProps | to pass custom styles , classes , ...etc all div attributes to only table head cells  | false | {} |


## notes
with props bodyProps, headerProps, bodyCellProps, headerCellProps you can pass any kind of attributes that could be passed to a normal html div element for the whole row (bodyProps) or each cell in the row (bodyCellProps) also for table header (headerProps) or each cell in the header (headerCellProps) , attributes like classes id onClick and and many more... 

![props](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bcbdd09bz4vbvyy9dd3.png)


![log output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kysnq0z38ietfuqzsaqi.png)


## and many more it's up to your creativity and imaginations
more about installation and configuration on npm gadwal page [gadwal on npm](https://www.npmjs.com/package/gadwal?activeTab=readme)