Skip to content
Snippets Groups Projects
Table.tsx 2.53 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
    // import './Table.css'
    
    import { ChangeEvent, MouseEvent } from "react";
    
    export interface Column {
      id: string
      name?: string,
    
    export interface Value {
      columnId: string,
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
      value: any
    }
    
    
      columns: Column[];
      data: Value[][];
      selectable?: boolean;
      selectedRows?: Set<number>;
      onClick?: (element: MouseEvent<HTMLTableRowElement>, index: number) => void
      onSelect?: (element: ChangeEvent<HTMLInputElement>, index: number) => void
    
    export const Table = (props: TableParams) => {
      const {
        columns,
        data,
        selectable = false,
        selectedRows,
        onClick,
        onSelect
      } = props;
    
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
      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}
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
                  {column.name}
    
                </th>)}
            </tr>
          </thead>
        );
      };
    
      const Body = () => {
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
        const rows = data.map(row => {
          return row.reduce((acc: any, item) => {
    
            acc[item.columnId] = item.value;
    
    Jacopo Gasparetto's avatar
    Jacopo Gasparetto committed
            return acc;
          }, new Map());
        })
    
    
        const columnIds = columns.map(col => col.id);
    
    
        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"
                          onChange={(el) => (onSelect && onSelect(el, rowIndex))}
                          checked={selectedRows && selectedRows.has(rowIndex)}
                        >
                        </input>
                      </th> : null
                  }
    
                  {columnIds.map((colId, 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
                    </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>