react-immutable-jss-data-table

Helps to show tables from Immutable collections, and stylize them using jss classes using React components

Usage no npm install needed!

<script type="module">
  import reactImmutableJssDataTable from 'https://cdn.skypack.dev/react-immutable-jss-data-table';
</script>

README

Show Immutalbe.List data in tables using jss for styling

usage

file sheet.js

export default {
  // default classNames
  DataTable: {
    // root
  },
  thead: {},
  tbody: {},
  tr: {},
  trEven: {},
  trOdd: {},
  trh: {},
  th: {},
  td: {},
  tdEmpty: {},
  // your own classNames
  thumb: {},
};

file pageWithTable.js

import React from 'react';
import DataTable from 'react-immutable-jss-data-table';
import sheet from './sheet.js';
// your jss injectSheet instance
import injectSheet from 'lib/sheet';
import tableColumns from './columns.jsx'

const columns = tableColumns.select('title', 'link', 'user', 'clickMe');

class MyPage extends React.PureComponent {
  render() {
    const { classes, list } = this.props;
    return (
      <div
        className={classes.container}
      >
        <DataTable
          classes={classes}
          columns={columns}
          items={list}
        />
      </div>
    );
  }
}

export default injectSheet(sheet)(MyPage);

define table columns

You can use fieldPath: ['path', 'to', 'val', 'in', 'rowData'] (rowData.getIn(fieldPath) will be used), or define your own getValue function, or even pass React component as render: CustomCellComponent.

import React from 'react';
import I from 'immutable';
import { columnsSelector } from 'react-immutable-jss-data-table';

export const columns = {
  // use rowIndex:
  cell0: {
    getValue: ({ rowIndex }) => `# ${rowIndex}`,
  },
  // add extra class, it will be searched in classes prop or cellClasses prop or used as is
  cell1: {
    className: 'my-own-class-name',
  },
  cell2: {
    // you can cpecify how to extract data from entries (rowData.getIn(fieldPath))
    fieldPath: ['article', 'title'],
    // then you can change the value
    getValue: ({ value }) => `Title: ${value}`,
  },
  cell3: {
    // how to extract data from rowData,
    fieldPath: ['article', 'title'],
    // then you can change the value
    getValue: ({ value, rowData }) => `Title: ${value}`,
    // you can render cell using your own component
    render: ({ value, rowData }) => <li children={'changed value: ' + value} />,
    // React component also can be used
    render: CustomCellComponent,
  },
  // if you whant to show column titles in table, please use 'title' prop
  cell4: {
    fieldPath: ['someField'],
    // column title (th)
    title: 'colum title',
    // you can change default title, f.e. add items amout
    getValueTh: ({ value, items }) => `${value} (${itmes.size})`,
    // render th using your own component
    renderTh: hoToRenderTh,
  },
  // you can change cell inner content markup using getValue:
  link: {
    fieldPath: ['article', 'url'],
    getValue: ({ value }) => <Link to={value} />,
  },
  // use DataTable props (<DataTable user={user}/>)
  user: {
    fieldPath: ['userId'],
    getValue: ({ classes, rowData, value, rowIndex, user }) =>
      <div
        className={classes.thumb}
        children={users.getFullNameById(value)}
      />,
  },
  // change cell markup fully
  clickMe: {
    render: ({ className, classes, rowData, value, rowIndex, props }) =>
      <div
        className={className}
        children={value}
        onClick={() => props.toggleEditRow(rowIndex)}
      />
  },
  // see definition bellow
  select: null,
};
columns.select = columnsSelector(columns);

export default columns;

available options for columns:

  • fieldPath - array used for Immutable.getIn method to extract value from rowData
  • className - custom className, used as additional className for cell
  • getValue - func, returns node or string or number, that will be placed as child in cell node
  • getValueTh - func, returns node or string or number, that will be placed as child in th node
  • render - func returns node, replaces cell root node
  • title - will be used as column title (like table > th) if showColumnsTitles set to true
  • getValueTh - allows to set column title using columnDef, and all DataTable props
  • renderTh - allows to render column, used as title for table, with your own React component
  • any other props, you can use in render, renderTh, getValue, getValueTh, Cell, ...

see properties for more details

see column definition examples

You can set your own component to render rows, or decide wich one to use

import DataTable, { Row } from 'react-immutable-jss-data-table';
const getRowRenderer = (props) => {
  const { rowData, rowIndex, ...allDataTableProps } = props;
  const Renderer = rowIndex === customRowIndex ? MyCustomRow : Row;
  return <Renderer {...props} />
}
<DataTable
  // ...
  Row={getRowRenderer}
/>

Customise empty row component, default RowEmpty can be used for your purposes

import DataTable, { RowEmpty } from 'react-immutable-jss-data-table';

const CustomRowEmpty = (props) =>
  rowIndex == 1 ? <MyEmptyRowComponent /> : <RowEmpty {...props} />;

<DataTable
  // ...
  RowEmpty={CustomRowEmpty}
/>

set your own Th / Cell components

import DataTable, { Th, Cell } from 'react-immutable-jss-data-table';

<DataTable
  // ...
  Th={Th}
  Cell={Cell}
/>

THead component example

import DataTable from 'react-immutable-jss-data-table';

const THead = ({ children, classes, ...otherDataTableProps }) =>
  <div className={classes.thead} children={children} />;


<DataTable
  // ...
  THead={THead}
/>

TBody component example

import DataTable from 'react-immutable-jss-data-table';

const TBody = ({ children, classes, ...otherDataTableProps }) =>
  <div className={classes.tbody} children={children} />;


<DataTable
  // ...
  TBody={TBody}
/>

Exported components and helpers

import DataTable, {
  // default getters
  renderTh,
  getValueTh,
  getValue,
  renderCell,
  // components
  Th,
  TBody,
  THead,
  Row,
  RowEmpty,
  Cell,
  DataTable,
  // sheet example
  sheet,
  // helpers
  getCellClassNames,
  getThClassNames,
  getRowClassNames,
  getColumnDef,
  columnsSelector,
} from 'react-immutable-jss-data-table';

properties

component prop type description
DataTable      
  columns array array with column definitions
  items I.List Immutable.List with data for table
  classes object jss classes
  getRowClassNames function return array with classnames
  getCellClassNames function return array with classnames
  getThClassNames function return array with classnames
  showColumnsTitles boolean display row.trh with titles.th
  className string additional table className
  Cell component component
  Th component component
  RowEmtpy component component
  Row component component
  renderTh renderable default fn for columnDef.renderTh
  getValueTh renderable default fn for columnDef.getValueTh
  getValue renderable default fn for columnDef.getValue for Cell
  render renderable default fn for columnDef.render for Cell
  defaultValue any defaultValue for Cell
Row      
  rowIndex integer
  rowData I.Map Immutable.Map with data for row
  DataTable props
TBody      
  children
  DataTable props
THead      
  children
  DataTable props
Th      
  title columnDef.title
  columnDef columns.map(columnDef => ...) column options, column definition
  getValueTh columnDef.getValueTh
  renderTh columnDef.renderTh
  DataTable props
Cell      
  columnDef object columns.map(columnDef => ...) column options, column definition
  value any extracted by
  rowData I.Map items.map(rowData => ...)
  rowIndex integer
  render component
  getValue component columnDef getValue
  fieldPath array rowData.getIn(fieldPath) used later in columnDef getValue
  defaultValue any cell default value, returned by getValue
  DataTable props
RowEmpty      
  DataTable props

getters

getter prop type description
getValue
  value any
  fieldPath array
  rowData I.Map
  rowIndex integer row order bumber based on 0
  columnDef object column options, column definition
  DataTable props
render
  value any
  fieldPath array
  rowData I.Map
  rowIndex integer row order bumber based on 0
  className string
  columnDef object column options, column definition
  DataTable props
getValueTh returns title for table column
  value any columnDef.title column options
  columnDef object column options, column definition
  DataTable props
renderTh
  value any returned by getValueTh
  className string
  columnDef object column options, column definition
  DataTable props

columnDef getValue

let value = rowData.getIn(fieldPath);
value = getValue ? getValue({ value, columnDef, rowData, rowIndex, ...props });

columnsSelector

// file ./columns.js
import { columnsSelector } from 'react-immutable-jss-data-table';
const COLUMNS_DEF = { title, link, user, clickMe, select: null };
COLUMNS_DEF.select = columnsSelector(COLUMNS_DEF);
export default COLUMNS_DEF;

// file with table
import DataTable from 'react-immutable-jss-data-table';
import tableColumns from './columns.js';
const columns = tableColumns.select('title', 'link', 'user', 'clickMe');

// in your component with table
<DataTable
  columns={columns}
  items={items}
  ...
/>

getColumnDef

// file ./columns.js
import { getColumnDef } from 'react-immutable-jss-data-table';
export default const COLUMNS_DEF = {
  title, link, user, clickMe,
  select: (...keys) => keys.map(col => getColumnDef(COLUMNS_DEF, col)),
};

// file with table
import DataTable from 'react-immutable-jss-data-table';
import tableColumns from './columns.js';
const columns = tableColumns.select('title', 'link', 'user', 'clickMe');

// in your component with table
<DataTable
  columns={columns}
  items={items}
  ...
/>