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

antd-data-table

v1.0.1

Published

[![npm](https://img.shields.io/npm/dm/antd-data-table.svg)](https://www.npmjs.com/package/antd-data-table) [![npm](https://img.shields.io/npm/v/antd-data-table.svg)](https://www.npmjs.com/package/antd-data-table) [![Build Status](https://travis-ci.org/New

Downloads

766

Readme

antd-data-table

npm npm Build Status antd

A component that combines antd's Table and Form to do the search, display, and operating jobs for data.

Feature

Free from:

  • Handling pagination
  • Handling table row selection
  • Writing search field form item components
  • Writing row actions components

Just focus on:

  • Doing the data fetching request and return the data
  • Rendering a specific data field if needed
  • Writing plugin to operate one or many data object(s)

Install

$ yarn add antd-data-table --save

Simplest data table

Demo

import { DataTable } from 'antd-data-table'

const searchFields: SearchField[] = [
  {
    label: 'ID',
    name: 'id',
    type: 'input',
    payload: {
      props: {
        placeholder: 'placeholder'
      }
    }
  },
  {
    label: 'Select',
    name: 'select',
    type: 'select',
    payload: {
      options: [
        { key: '1', label: 'one', value: '1' },
        { key: '2', label: 'two', value: '2' },
        { key: '3', label: 'three', value: '3' }
      ]
    }
  }
]

const columns: TableColumnConfig<any>[] = [
  {
    key: 'id',
    title: 'ID',
    dataIndex: 'id'
  }, {
    key: 'title',
    title: 'Title',
    dataIndex: 'title'
  }
]

const expands: Expand[] = [
  {
    title: 'Body',
    dataIndex: 'body',
    render (value) {
      return value && `${value.substr(0, 100)} ...`
    }
  },
  {
    title: 'User ID',
    dataIndex: 'userId'
  }
]

const onSearch = async ({ page, pageSize, values }) => {
  const res = await axios.get('http://jsonplaceholder.typicode.com/posts', {
    params: {
      _page: page,
      _limit: pageSize,
      ...values
    }
  })
  return {
    dataSource: res.data,
    total: Number(res.headers['x-total-count'])
  }
}
render(
  <DataTable
    rowKey={record => record.id}
    searchFields={searchFields}
    initialColumns={columns}
    initialExpands={expands}
    onSearch={onSearch}
  />
, mountNode)

Guide

Collapsable search field

Sometimes there are many search fields, you could set a maxVisibleFieldCount to automatically have a collapsable form:

Demo

import { DataTable } from 'antd-data-table'

render(
  <DataTable
    rowKey={record => record.id}
    searchFields={searchFields}
    initialColumns={columns}
    onSearch={onSearch}
+   maxVisibleFieldCount={4}
  />
, mountNode)

Row actions

We usually need to write some action buttons for operating a specific record. antd-data-table made it super easy:

Demo

const actions: RowAction[] = [
  {
    label: 'Edit',
    action (record) {
      action('onClick edit')(record)
    }
  },
  {
    label: 'More',
    children: [
      {
        label: 'Remove',
        action (record) {
          action('onClick remove')(record)
        }
      },
      {
        label: 'Open',
        action (record) {
          action('onClick open')(record)
        }
      }
    ]
  }
]

render(
  <DataTable
    rowKey={record => record.id}
    searchFields={searchFields}
    initialColumns={columns}
    initialExpands={expands}
    onSearch={onSearch}
    actions={actions}
  />
, mountNode)

Plugins

Plugins are for operating multiple records. Every plugin will render a component at the top of table.

Demo

Let's write a simplest plugin: A button that show current selected rows' ids:

const ShowIdsBtn = ({ selectedRows, clearSelection }) => {
  const showIds = () => {
    message.info(selectedRows.map(row => row.id).join(','))
    // clear selection after the action is done
    clearSelection()
  }

  return <Button onClick={showIds}>Show Ids</Button>
}

const plugins = [
  renderer (selectedRowKeys, selectedRows, clearSelection) {
    return <ShowIdsBtn selectedRows={selectedRows} clearSelection={clearSelection} />
  }
]

render (
  <DataTable
    rowKey={record => record.id}
    searchFields={searchFields}
    plugins={plugins}
    initialColumns={columns}
    initialExpands={expands}
    onSearch={onSearch}
  />
, mountNode)

Props

name?: string

Unique table name.

rowKey: (record) => string

The key value of a row.

searchFields: SearchField[]

SearchField is an object that contains:

  • label: string Pass to <Form.Item>'s label property.
  • name: string Pass to getFieldDecorator as the decorator name.
  • type?: RenderType antd-data-table comes with some common form item type. Such as input, select.
  • initialValue?: any Inital form value.
  • renderer?: (payload?: object) => React.ReactNode When the form item types are not statisfied, your could write your own renderer. the ReactNode that returned will be wrapped by getFieldDecorator.
  • validationRule?: ValidateionRule[] antd validation rules. Pass to getFieldDecorator(name, { rules }).
  • payload?: { props: any, [key: string]: any } Some params that pass to the renderer.
  • span?: number Form Item Col span value. 6 by default.

out of the box render type

input
interface payload {
  props: object // antd Input props
}

datePicker

interface payload {
  props: object // antd DatePicker props
}

treeSelect

interface payload {
  props: object // antd TreeSelect props
}
select
interface payload {
  props: object, // antd Select props
  options: {
    key: string,
    label: string,
    value: string
  }[]
}

initialColumns: TableColumnConfig[]

antd's TableColumnConfig. See more at https://ant.design/components/form/

initialExpands: Expand[]

type Expand = {
  /** Title of this column **/
  title: string,
  /** Display field of the data record, could be set like a.b.c **/
  dataIndex: string,
  /** Renderer of the column in the expanded. The return value should be a ReactNode **/
  render?: (text: any, record?: {}) => React.ReactNode
}

onSearch<T> (info: SearchInfo): Promise<SearchResponse<T>>

onSearch property need a function that return a Promise, which resolves an object that contains total and dataSource. This function receive a SearchInfo:

type SearchInfo = {
  /** values from `getFieldsValue()` */
  values: any,
  /** current page */
  page: number,
  /** page size */
  pageSize: number
}

title?: React.ReactNode

searchBtnText?: string

clearBtnText?: string

listSelectionBtnText?: string

onError? (err): void

Error handler that trigger when onSearch throw error.

loadDataImmediately?: boolean

Load list data immediately, default is false

onValidateFailed?: (err: ValidateError) => void

Form validation failed handler

pageSize?: number

default is 10

plugins?: Plugin[]

rowActions?: RowAction[]

enableListSelection?: boolean

If true, a list selection button will display on table title.

Be sure to pass the name props if it is enable.

rowSelection?: TableRowSelection

Custom rowSelection.

affixTarget?: () => HTMLelement

For Affix. Specifies the scrollable area dom node

affixOffsetTop?: number

Pixels to offset from top when calculating position of scroll

affixOffsetBottom?: number

Pixels to offset from bottom when calculating position of scroll

FAQ

How to trigger the onSearch action imperatively?

There is a public fetch method in DataTable to do this action. So you could get it from ref:

Demo

// ...
render () {
  let dataTableRef: DataTable | null = null

  const saveDataTableRef = (ref: DataTable) => {
    dataTableRef = ref
  }

  const onClickCustomSearch = () => {
    if (dataTableRef) {
      dataTableRef.fetch(1)
    }
  }

  return (
    <div style={{ padding: '1em' }}>
      <DataTable
        ref={saveDataTableRef}
        name='customSearch'
        rowKey={record => record.id}
        searchFields={searchFields}
        initialColumns={columns}
        initialExpands={expands}
        onSearch={onSearch}
        pageSize={10}
        onError={onError}
      />
      <Button onClick={onClickCustomSearch}>Custom Search</Button>
    </div>
  )
}

fetch: async (page: number, values: object = this.state.currentValues, clearPagination: boolean = false)

Build

$ yarn

$ yarn start # start the storybook

$ yarn test # run the test

$ yarn run build # build the distribution file

$ yarn run build:storybook # build storybook

Release workflow

$ yarn run build:storybook # build storybook

$ npm publish

License

MIT License