Working with Columns

Columns are a central feature in InfiniteTable. You define columns as a Map<string, InfiniteTableColumn<DATA_TYPE>> (or as an object) and then use pass them in the columns prop in your InfiniteTable component.

Note

In InfiniteTable, columns are identified by their key in the columns Map/object. We’ll refer to this as the column id. The column ids are used in many places - like defining the columnOrder, column pinning, column visibility, etc.

export type Employee = {
  id: number;
  companyName: string;
  firstName: string;
  lastName: string;
  country: string;
  city: string;
  department: string;
  team: string;
  salary: number;
  
};

// InfiniteTableColumn is a generic type, you have to bind it to a specific data-type
import { InfiniteTableColumn } from '@infinite-table/infinite-react';

export const columns = new Map<
  string,
  // we're binding it here to the `Employee` type
  // which means the `column.field` has to be `keyof Employee`
  InfiniteTableColumn<Employee>
>([
  [
    'firstName',
    {
      field: 'firstName',
      header: 'First Name',
    },
  ],
  [
    'country',
    {
      field: 'country',
    },
  ],

  [
    'city',
    {
      field: 'city'
    },
  ],
  [
    'salary',
    {
      field: 'salary',
      type: 'number'
    },
  ],
]);

<InfiniteTable columns={columns} />

Gotcha

It’s very important to remember you should not pass a different reference of a prop on each render. <InfiniteTable /> is a optimized to only re-render when props change - so if you change the props on every re-render you will get a performance penalty.

You should use React.useCallback / React.useMemo / React.useState to make sure you only update the props you pass down to InfiniteTable when you have to.

Basic Column Configuration
Fork
import * as React from 'react';
import {
  InfiniteTable,
  DataSource,
} from '@infinite-table/infinite-react';

import { InfiniteTableColumn } from '@infinite-table/infinite-react';

export type Employee = {
  id: number;
  companyName: string;
  companySize: string;
  firstName: string;
  lastName: string;
  country: string;
  countryCode: string;
  city: string;
  streetName: string;
  streetNo: string;
  department: string;
  team: string;
  salary: number;
  age: number;
  email: string;
};

export const columns = new Map<
  string,
  InfiniteTableColumn<Employee>
>([
  [
    'firstName',
    {
      field: 'firstName',
      header: 'First Name',
    },
  ],
  [
    'country',
    {
      field: 'country',
      header: 'Country',
      columnGroup: 'location',
    },
  ],

  [
    'city',
    {
      field: 'city',
      header: 'City',
      columnGroup: 'address',
    },
  ],
  [
    'salary',
    {
      field: 'salary',
      type: 'number',
      header: 'Salary',
    },
  ],
  [
    'department',
    {
      field: 'department',
      header: 'Department',
    },
  ],
  [
    'team',
    {
      field: 'team',
      header: 'Team',
    },
  ],
  ['company', { field: 'companyName', header: 'Company' }],
  [
    'companySize',
    { field: 'companySize', header: 'Company Size' },
  ],
]);

export default function App() {
  return (
    <DataSource<Employee> data={dataSource} primaryKey="id">
      <InfiniteTable<Employee>
        columns={columns}
        columnDefaultWidth={200}
      />
    </DataSource>
  );
}

const dataSource = () => {
  return fetch(
    'https://infinite-table.com/.netlify/functions/json-server' + '/employees100'
  )
    .then((r) => r.json())
    .then((data: Employee[]) => data);
};

Column Types

For now there are only 2 column types, but more are coming soon:

  • string - the default type, if none is specified.
  • number

Specifying the correct column type will ensure the correct sorting function is used.

Column Order

The implicit column order is the order in which columns have been defined in the columns Map. You can however control that explicitly by using the columnOrder: string[] prop.

The columnOrder prop is an array of strings, representing the column ids. A column id is the key of the column in the columns Map.

Note

The columnOrder array can contain identifiers that are not yet defined in the columns Map, or can contain duplicate ids. This is a feature, not a bug. We want to allow you to use the columnOrder in a flexible way so it can define the order of current and future columns.

Note

columnOrder is a controlled prop. For uncontrolled version, see defaultColumnOrder
Column Order demo, with firstName col displayed twice
Fork
import * as React from 'react';
import {
  InfiniteTable,
  DataSource,
} from '@infinite-table/infinite-react';

import { InfiniteTableColumn } from '@infinite-table/infinite-react';

export type Employee = {
  id: number;
  companyName: string;
  companySize: string;
  firstName: string;
  lastName: string;
  country: string;
  countryCode: string;
  city: string;
  streetName: string;
  streetNo: string;
  department: string;
  team: string;
  salary: number;
  age: number;
  email: string;
};

export const columns = new Map<
  string,
  InfiniteTableColumn<Employee>
>([
  [
    'firstName',
    {
      field: 'firstName',
      header: 'First Name',
    },
  ],
  [
    'country',
    {
      field: 'country',
      header: 'Country',
      columnGroup: 'location',
    },
  ],

  [
    'city',
    {
      field: 'city',
      header: 'City',
      columnGroup: 'address',
    },
  ],
  [
    'salary',
    {
      field: 'salary',
      type: 'number',
      header: 'Salary',
    },
  ],
  [
    'department',
    {
      field: 'department',
      header: 'Department',
    },
  ],
  [
    'team',
    {
      field: 'team',
      header: 'Team',
    },
  ],
  ['company', { field: 'companyName', header: 'Company' }],
  [
    'companySize',
    { field: 'companySize', header: 'Company Size' },
  ],
]);

export default function App() {
  const columnOrder = React.useMemo(
    () => [
      'firstName',
      'country',
      'team',
      'company',
      'firstName',
      'not existing',
      'companySize',
    ],
    []
  );
  return (
    <DataSource<Employee> data={dataSource} primaryKey="id">
      <InfiniteTable<Employee>
        columns={columns}
        columnOrder={columnOrder}
        columnDefaultWidth={200}
      />
    </DataSource>
  );
}

const dataSource = () => {
  return fetch(
    'https://infinite-table.com/.netlify/functions/json-server' + '/employees100'
  )
    .then((r) => r.json())
    .then((data: Employee[]) => data);
};