npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-smart-data-table

v0.16.0

Published

A smart data table component for React.js meant to be configuration free

Downloads

694

Readme

react-smart-data-table

npm version jest Contributor Covenant Workflow Status Total alerts Language grade: JavaScript

A smart data table component for React.js meant to be configuration free, batteries included.

About

This is meant to be a zero configuration data table component for React.js in the spirit of plug and play.

Just feed it an array of equal JSON objects and it will create a template free table that can be customized easily with any framework (or custom CSS).

If you want more control over the data rendering process or don't need the smarts, check out react-very-simple-data-table.

Features

It currently supports:

  1. Humanized column names based on object keys
  2. Sortable columns
    • Accepts a custom sort compareFn function
  3. Rows filtering / searchable
  4. Search term highlight in the results
  5. Column visibility toggles
  6. Automatic pagination
  7. Server-side/remote data
  8. Control over row clicks
  9. Smart data rendering
    • URLs and E-Mail addresses rendered as the href in an anchor tag <a />
    • boolean value parsing to yes/no word
    • Image URLs rendered as the src for an image tag <img />
  10. Custom override if the default behavior is unwanted for some columns
  11. Custom components
    • Paginator
  12. Control the order of the columns
    • Using the above, it's also possible to select which columns to display

Installation

yarn add react-smart-data-table

# or

npm install react-smart-data-table

There is some very basic styling you can use to get started, but since v0.8.0 you need to import it specifically. You can also copy the file and use it as the basis for your own theme.

// Import basic styling
import 'react-smart-data-table/dist/react-smart-data-table.css'

Context

You can access the SmartDataTable's internal context in your own component by using the useSmartDataTableContext hook.

Note: You must be within the context of SmartDataTable, e.g. passing a custom component to emptyTable, loading, or paginator.

import { useSmartDataTableContext } from 'react-smart-data-table'

const MyComponent = () => {
  const { columns, data } = useSmartDataTableContext()

  return (
    <div>
      <h3>My Component</h3>
      <p>
        Columns: {columns.length}
      </p>
      <p>
        Rows: {data.length}
      </p>
    </div>
  )
}

Props

| Name | Default | Type | Description | | :----------------- | :-------------------- | :-------------------- | :---------------------------------------------------------------- | | data | [] | {array|string} | An array of plain objects (can be nested) or a URL | | dataKey | 'data' | {string} | The object key where the async data is available | | dataKeyResolver | null | {function} | Supply a function to extract the data from the async response | | dataRequestOptions | {} | {object} | Fetch API options passed directly into the async request call | | dataSampling | 0 | {number} | Percentage of the data to sample before computing the headers | | dynamic | false | {boolean} | Use this if your column structure changes dynamically | | emptyTable | null | {element} | Pass a renderable object to render when there is no data | | filterValue | '' | {string} | Filters all columns by its value | | headers | {} | {object} | The object that overrides default column behavior | | hideUnordered | false | {boolean} | Hides all the columns not passed to orderedHeaders | | loader | null | {element} | Element to be rendered while fetching async data | | name | 'reactsmartdatatable' | {string} | The name for the table | | onRowClick | undefined | {function} | If present, it will execute on every row click | | orderedHeaders | [] | {array} | An ordered array of the column keys | | paginator | elements | {element} | Pass a renderable object to handle the table pagination | | parseBool | false | {boolean|object} | When true, boolean values will be converted to Yes/No | | parseImg | false | {boolean|object} | When true, image URLs will be rendered as an img tag | | perPage | 0 | {number} | Paginates the results with the value as rows per page | | sortable | false | {boolean} | Enables the columns of the table to be sortable | | withFooter | false | {boolean} | Copy the header to the footer | | withHeader | true | {boolean} | Can be used to disable the rendering of column headers | | withLinks | false | {boolean} | Converts e-mails and url addresses to links | | withToggles | false | {boolean|object} | Enables the column visibility toggles |

emptyTable

// Any renderable object can be passed
const emptyTable = <div>There is no data available at the time.</div>

headers

/*
  Use the following structure to overwrite the default behavior for columns
  Undefined column keys will present the default behavior
    text:       Humanized text based on the column key name
    invisible:  Columns are visible by default
    sortable:   Columns are sortable by default
    filterable: Columns are filterable by default
    isImg:      Will force the render as an image, e.g. for dynamic URLs
    transform:  Allows the custom rendering of the cells content
                Should be a function and these are the arguments passed:
                  (value, index, row)
                The index is the position of the row as being rendered and
                not the index of the row in the original data
  Nested structures can be defined by a string-dot representation
    'key1.key2.key3.[...].key99'
*/
const headers = {
  columnKey: {
    text: 'Column 1',
    invisible: false,
    sortable: true,
    filterable: true,
  },
  'nested.columnKey': {
    text: 'Nested Column',
    invisible: false,
    sortable: (a, b) => b['nested.columnKey'] - a['nested.columnKey'],
    filterable: true,
  },
  // If a dummy column is inserted into the data, it can be used to customize
  // the table by allowing actions per row to be implemented, for example
  tableActions: {
    text: 'Actions',
    invisible: false,
    sortable: false,
    filterable: false,
    transform: (value, index, row) => {
      // The following results should be identical
      console.log(value, row.tableActions)
      // Example of table actions: Delete row from data by row index
      return <button onClick={() => deleteRow(row)}>Delete Row</button>
    },
  },
}

onRowClick()

const onRowClick = (event, { rowData, rowIndex, tableData }) => {
  // The following results should be identical
  console.log(rowData, tableData[rowIndex])
}

paginator

The CustomComponent passed down as a prop will be rendered with the following props which can be used to perform all the necessary calculations and makes it fully compatible with Semantic UI's Pagination component.

const CustomComponent = ({
  activePage, totalPages, onPageChange,
}) => (/* ... */)

<SmartDataTable
  // ...
  paginator={CustomComponent}
/>

// To change the page, call the onPageChange function with the next activePage

<MyCustomElement
  // ...
  onClick={e => this.onPageChange(e, { activePage: nextActivePage })}
/>

parseBool

// Default
const parseBool = {
  yesWord: 'Yes',
  noWord: 'No',
}

parseImg

// You can pass a regular style object that will be passed down to <img />
// Or a Class Name
const parseImg = {
  style: {
    border: '1px solid #ddd',
    borderRadius: '4px',
    padding: '5px',
    width: '150px',
  },
  className: 'my-custom-image-style',
}

orderedHeaders / hideUnordered

If you want to control the order of the columns, simply pass an array containing the keys in the desired order. All the omitted headers will be appended afterwards unpredictably. Additionally, you can pass the hideUnordered in order to render only the headers in orderedHeaders and hide the remaining.

const hideUnordered = true

const orderedHeaders = [
  'key1',
  'key2.subkey3',
  ...
]

withToggles

You can control the Toggles by passing an object with the following structure:

// Default toggles enabled
const withToggles = true

// Default toggles enabled with default select all
const withToggles = {
  selectAll: true,
}

// Toggles with a custom locale
const withToggles = {
  // The options to be passed as props to the `SelectAll` component
  selectAll: {
    // The text to be displayed in the Select All input
    locale: {
      // The default label for the `unchecked` state
      selectAllWord: 'Select All',
      // The default label for the `checked` state
      unSelectAllWord: 'Unselect All',
    },
    // You should not need to use this, but it is here for completeness
    handleToggleAll: (isChecked: boolean): void => {
      // ...
    },
  },
}

Examples

Async data loading (fetch)

By passing a string to the data prop, the component will interpret it as an URL and try to load the data from that location using fetch. If a successful request is returned, the data will be extracted from the response object. By default, it will grab the data key from the response. If it's in a different key, you can specify it with the dataKey prop. Just in case it's not a first-level attribute, you can supply a custom function to locate the data using the dataKeyResolver prop.

response from /api/v1/user

{
  "status": "success",
  "message": "",
  "users": [{ "id": 0, "other": "..." }, { "id": 1, "other": "..." }, "..."]
}

response from /api/v1/post

{
  "status": "success",
  "message": "",
  "results": {
    "posts": [{ "id": 0, "other": "..." }, { "id": 1, "other": "..." }, "..."]
  }
}

component

// Using `dataKey`
<SmartDataTable
  data="/api/v1/user"
  dataKey="users"
  name="test-table"
/>

// Using `dataKeyResolver`
<SmartDataTable
  data="/api/v1/post"
  dataKeyResolver={(response) => response.results.posts}
  name="test-table"
/>

Simple sortable table (with Semantic UI)

import React from 'react'
import ReactDOM from 'react-dom'
import faker from 'faker'
import SmartDataTable from 'react-smart-data-table'

const testData = []
const numResults = 100

for (let i = 0; i < numResults; i++) {
  testData.push({
    _id: i,
    fullName: faker.name.findName(),
    'email.address': faker.internet.email(),
    phone_number: faker.phone.phoneNumber(),
    address: {
      city: faker.address.city(),
      state: faker.address.state(),
      country: faker.address.country(),
    },
  })
}

ReactDOM.render(
  <SmartDataTable
    data={testData}
    name="test-table"
    className="ui compact selectable table"
    sortable
  />,
  document.getElementById('app'),
)

Demos

You can try react-smart-data-table with different UI libraries in the demo pages below. You can experiment with different features as well.

Take a look at the full featured example's source code.

Also, see it in full integration with a simple user/group management dashboard application. Feel free to play around with it, it's built with hot reloading.

If you want to play around, check out this codepen.

FAQ

If you're having trouble with react-smart-data-table, please check out the answers below. Otherwise, feel free to open a new issue!

  • Check this answer to see how to hide the pagination for an empty table
  • Check this answer if you're integrating with Server Side Rendering (SSR)
  • Check this answer if you want to implement a double click event on a row
  • Check this answer if you want to control the active page manually (e.g., based on a URL parameter)
  • Check this answer if you want to style individual columns differently

Forking / Contributing

If you want to fork or contribute, it's easy to test your changes. Just run the following development commands. The start instruction will start a development HTTP server in your computer accessible from your browser at the address http://localhost:3000/.

yarn start