Skip to content
Snippets Groups Projects
Table.tsx 2.05 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
    // import './Table.css'
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
    
    export type Column = {
      name: string,
      columnType: "boolean" | "number" | "string";
    }
    
    export type Value = {
      columnName: string,
      value: any
    }
    
    
    type TableParams = {
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
      columns: Column[],
      data: Value[][],
      selectable?: boolean
    
      onClick?: (element: React.MouseEvent<HTMLTableRowElement>, index: number) => void
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
    export const Table = ({ columns, data, selectable = false, onClick }: TableParams) => {
      const thClassName = "border-b font-medium p-4 first:pl-8 last:pr-8 pt-0 pb-3 \
        text-left text-slate-800";
    
      const Header = () => {
        return (
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
          <thead>
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
              {selectable ? <th></th> : null}
    
              {columns.map(column =>
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
                <th
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
                  className={thClassName}
                  key={column.name}>
                  {column.name}
    
                </th>)}
            </tr>
          </thead>
        );
      };
    
      const Body = () => {
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
        const columnNames = columns.map(col => col.name);
        const rows = data.map(row => {
          return row.reduce((acc: any, item) => {
            acc[item.columnName] = item.value;
            return acc;
          }, new Map());
        })
    
    
        return (
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
          <tbody className="bg-white">
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
              rows.map((row, rowIndex) => {
    
                return <tr
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
                  className="hover:bg-slate-200 text-slate-500
                   hover:text-slate-800 hover:cursor-pointer"
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
                  onClick={(el) => onClick?.(el, rowIndex)}
                  key={rowIndex}>
                  {selectable ? <th className="pl-4"><input type="checkbox"></input></th> : null}
                  {columnNames.map((colName, index) => {
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
                    return <td
                      className="border-b border-slate-100 
                      p-4 first:pl-8 last:pr-8 text-left"
                      key={index}>
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
                      {row[colName]}
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
                    </td>
    
      return (
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
        <div className="w-full bg-slate-100 shadow-lg rounded-xl">
          <table className={"table-auto w-full text-sm mt-8 mb-6"}>
            <Header />
            <Body />
          </table>
        </div>