CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-table

Hooks for building lightweight, fast and extendable datagrids for React

Pending
Overview
Eval results
Files

layout.mddocs/

Layout Systems

React Table provides specialized layout plugins that enable different rendering approaches for tables. These layout systems optimize performance and provide specific styling capabilities for different use cases.

Capabilities

Absolute Layout (useAbsoluteLayout)

Provides absolute positioning layout for high-performance tables with fixed dimensions.

/**
 * Adds absolute positioning layout to the table
 * @param hooks - Hook registration object
 */
function useAbsoluteLayout(hooks: Hooks): void;

Usage Example:

import React from 'react';
import { useTable, useAbsoluteLayout } from 'react-table';

function AbsoluteLayoutTable({ columns, data }) {
  const defaultColumn = React.useMemo(
    () => ({
      width: 150,
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    totalColumnsWidth,
  } = useTable(
    {
      columns,
      data,
      defaultColumn,
    },
    useAbsoluteLayout
  );

  return (
    <div
      {...getTableProps()}
      style={{
        position: 'relative',
        width: totalColumnsWidth,
        height: 400,
        overflow: 'auto',
        border: '1px solid black',
      }}
    >
      <div>
        {headerGroups.map(headerGroup => (
          <div {...headerGroup.getHeaderGroupProps()} className="tr">
            {headerGroup.headers.map(column => (
              <div {...column.getHeaderProps()} className="th">
                {column.render('Header')}
              </div>
            ))}
          </div>
        ))}
      </div>
      
      <div {...getTableBodyProps()}>
        {rows.map(row => {
          prepareRow(row);
          return (
            <div {...row.getRowProps()} className="tr">
              {row.cells.map(cell => (
                <div {...cell.getCellProps()} className="td">
                  {cell.render('Cell')}
                </div>
              ))}
            </div>
          );
        })}
      </div>
    </div>
  );
}

Block Layout (useBlockLayout)

Provides block-level layout with explicit width management for consistent column sizing.

/**
 * Adds block layout to the table
 * @param hooks - Hook registration object
 */
function useBlockLayout(hooks: Hooks): void;

Usage Example:

import React from 'react';
import { useTable, useBlockLayout, useResizeColumns } from 'react-table';

function BlockLayoutTable({ columns, data }) {
  const defaultColumn = React.useMemo(
    () => ({
      minWidth: 30,
      width: 150,
      maxWidth: 400,
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable(
    {
      columns,
      data,
      defaultColumn,
    },
    useBlockLayout,
    useResizeColumns
  );

  return (
    <div
      {...getTableProps()}
      style={{
        display: 'inline-block',
        border: '1px solid black',
      }}
    >
      <div>
        {headerGroups.map(headerGroup => (
          <div {...headerGroup.getHeaderGroupProps()} className="header-group">
            {headerGroup.headers.map(column => (
              <div {...column.getHeaderProps()} className="header">
                {column.render('Header')}
                {column.canResize && (
                  <div
                    {...column.getResizerProps()}
                    className="resizer"
                  />
                )}
              </div>
            ))}
          </div>
        ))}
      </div>
      
      <div {...getTableBodyProps()}>
        {rows.map(row => {
          prepareRow(row);
          return (
            <div {...row.getRowProps()} className="row">
              {row.cells.map(cell => (
                <div {...cell.getCellProps()} className="cell">
                  {cell.render('Cell')}
                </div>
              ))}
            </div>
          );
        })}
      </div>
      
      <style jsx>{`
        .header-group {
          display: flex;
        }
        .header {
          position: relative;
          background: #f5f5f5;
          border: 1px solid #ddd;
          padding: 8px;
          font-weight: bold;
        }
        .row {
          display: flex;
        }
        .cell {
          border: 1px solid #ddd;
          padding: 8px;
          overflow: hidden;
        }
        .resizer {
          position: absolute;
          right: 0;
          top: 0;
          height: 100%;
          width: 5px;
          background: rgba(0, 0, 0, 0.5);
          cursor: col-resize;
          user-select: none;
          touch-action: none;
        }
      `}</style>
    </div>
  );
}

Flex Layout (useFlexLayout)

Provides flexbox-based layout for responsive and flexible column sizing.

/**
 * Adds flexbox layout to the table
 * @param hooks - Hook registration object
 */
function useFlexLayout(hooks: Hooks): void;

Usage Example:

import React from 'react';
import { useTable, useFlexLayout } from 'react-table';

function FlexLayoutTable({ columns, data }) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable(
    {
      columns,
      data,
    },
    useFlexLayout
  );

  return (
    <div
      {...getTableProps()}
      style={{
        display: 'flex',
        flexDirection: 'column',
        border: '1px solid black',
        maxWidth: '100%',
      }}
    >
      <div>
        {headerGroups.map(headerGroup => (
          <div
            {...headerGroup.getHeaderGroupProps()}
            style={{
              display: 'flex',
              backgroundColor: '#f5f5f5',
            }}
          >
            {headerGroup.headers.map(column => (
              <div
                {...column.getHeaderProps()}
                style={{
                  padding: '10px',
                  border: '1px solid #ddd',
                  fontWeight: 'bold',
                  flex: column.totalFlexWidth ? `${column.totalFlexWidth} 0 auto` : '1 1 auto',
                }}
              >
                {column.render('Header')}
              </div>
            ))}
          </div>
        ))}
      </div>
      
      <div {...getTableBodyProps()}>
        {rows.map(row => {
          prepareRow(row);
          return (
            <div
              {...row.getRowProps()}
              style={{
                display: 'flex',
              }}
            >
              {row.cells.map(cell => (
                <div
                  {...cell.getCellProps()}
                  style={{
                    padding: '10px',
                    border: '1px solid #ddd',
                    flex: cell.column.totalFlexWidth ? `${cell.column.totalFlexWidth} 0 auto` : '1 1 auto',
                    overflow: 'hidden',
                  }}
                >
                  {cell.render('Cell')}
                </div>
              ))}
            </div>
          );
        })}
      </div>
    </div>
  );
}

Grid Layout (useGridLayout)

Provides CSS Grid-based layout for advanced grid positioning and alignment.

/**
 * Adds CSS Grid layout to the table
 * @param hooks - Hook registration object
 */
function useGridLayout(hooks: Hooks): void;

Usage Example:

import React from 'react';
import { useTable, useGridLayout } from 'react-table';

function GridLayoutTable({ columns, data }) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable(
    {
      columns,
      data,
    },
    useGridLayout
  );

  // Calculate grid template columns
  const gridTemplateColumns = headerGroups[0]?.headers
    .map(column => column.width || '1fr')
    .join(' ') || 'repeat(auto-fit, minmax(150px, 1fr))';

  return (
    <div
      {...getTableProps()}
      style={{
        display: 'grid',
        gridTemplateColumns,
        border: '1px solid black',
        gap: '1px',
        backgroundColor: '#ddd',
      }}
    >
      {/* Headers */}
      {headerGroups.map(headerGroup =>
        headerGroup.headers.map(column => (
          <div
            key={column.id}
            {...column.getHeaderProps()}
            style={{
              padding: '10px',
              backgroundColor: '#f5f5f5',
              fontWeight: 'bold',
              display: 'flex',
              alignItems: 'center',
            }}
          >
            {column.render('Header')}
          </div>
        ))
      )}
      
      {/* Body Cells */}
      {rows.map(row => {
        prepareRow(row);
        return row.cells.map(cell => (
          <div
            key={`${row.id}-${cell.column.id}`}
            {...cell.getCellProps()}
            style={{
              padding: '10px',
              backgroundColor: 'white',
              display: 'flex',
              alignItems: 'center',
            }}
          >
            {cell.render('Cell')}
          </div>
        ));
      })}
    </div>
  );
}

Layout Comparison and Use Cases

When to use each layout:

LayoutUse CaseProsCons
DefaultSimple tables, basic stylingEasy to style with CSS, familiar table markupLess control over column sizing
AbsoluteHigh-performance, virtualizationBest performance, precise positioningRequires fixed dimensions
BlockResizable columns, precise widthsWorks well with resizing, precise controlMore complex CSS
FlexResponsive tables, flexible sizingResponsive, flexible column distributionCan be complex with many columns
GridComplex layouts, advanced alignmentPowerful grid features, clean markupBrowser support considerations

Layout with Virtualization

Combine layout plugins with virtualization for handling large datasets.

import React from 'react';
import { FixedSizeList as List } from 'react-window';
import { useTable, useBlockLayout } from 'react-table';

function VirtualizedTable({ columns, data }) {
  const defaultColumn = React.useMemo(
    () => ({
      width: 150,
    }),
    []
  );

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    totalColumnsWidth,
    prepareRow,
  } = useTable(
    {
      columns,
      data,
      defaultColumn,
    },
    useBlockLayout
  );

  const RenderRow = React.useCallback(
    ({ index, style }) => {
      const row = rows[index];
      prepareRow(row);
      return (
        <div
          {...row.getRowProps({ style })}
          className="row"
        >
          {row.cells.map(cell => (
            <div {...cell.getCellProps()} className="cell">
              {cell.render('Cell')}
            </div>
          ))}
        </div>
      );
    },
    [prepareRow, rows]
  );

  return (
    <div {...getTableProps()}>
      <div>
        {headerGroups.map(headerGroup => (
          <div {...headerGroup.getHeaderGroupProps()} className="header-group">
            {headerGroup.headers.map(column => (
              <div {...column.getHeaderProps()} className="header">
                {column.render('Header')}
              </div>
            ))}
          </div>
        ))}
      </div>
      
      <div {...getTableBodyProps()}>
        <List
          height={400}
          itemCount={rows.length}
          itemSize={35}
          width={totalColumnsWidth}
        >
          {RenderRow}
        </List>
      </div>
    </div>
  );
}

Custom Layout Implementation

Create custom layout behaviors by implementing your own layout hook.

// Custom layout hook example
function useCustomLayout(hooks) {
  hooks.getTableProps.push((props, { instance }) => [
    props,
    {
      style: {
        display: 'table',
        borderCollapse: 'collapse',
        width: '100%',
      },
    },
  ]);

  hooks.getHeaderGroupProps.push((props) => [
    props,
    {
      style: {
        display: 'table-row',
      },
    },
  ]);

  hooks.getHeaderProps.push((props, { column }) => [
    props,
    {
      style: {
        display: 'table-cell',
        padding: '8px',
        border: '1px solid #ccc',
        backgroundColor: '#f5f5f5',
        fontWeight: 'bold',
        width: column.width,
      },
    },
  ]);

  hooks.getRowProps.push((props) => [
    props,
    {
      style: {
        display: 'table-row',
      },
    },
  ]);

  hooks.getCellProps.push((props, { cell }) => [
    props,
    {
      style: {
        display: 'table-cell',
        padding: '8px',
        border: '1px solid #ccc',
        width: cell.column.width,
      },
    },
  ]);
}

// Use custom layout
function CustomLayoutTable({ columns, data }) {
  const tableInstance = useTable(
    { columns, data },
    useCustomLayout
  );
  
  // Table implementation...
}

Types

interface LayoutInstance {
  /** Total width of all columns */
  totalColumnsWidth?: number;
}

interface LayoutColumn {
  /** Column width */
  width?: number;
  /** Minimum column width */
  minWidth?: number;
  /** Maximum column width */
  maxWidth?: number;
  /** Flex width for flex layout */
  totalFlexWidth?: number;
}

interface LayoutMeta {
  instance: TableInstance;
  column?: Column;
  row?: Row;
  cell?: Cell;
}

Install with Tessl CLI

npx tessl i tessl/npm-react-table

docs

built-in-types.md

column-management.md

core-table.md

filtering.md

grouping.md

index.md

layout.md

pagination.md

row-features.md

sorting.md

utilities.md

tile.json