1.13.96 • Published 2 years ago

@myntra/uikit-component-table v1.13.96

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

import Table from './src/table' import { EllipsisVSolid } from 'uikit-icons'

Table

const [value, setValue] = useState();
const [data] = useState([
  { id: 1, name: 'Jane Doe', age: 24, status: 'single', visits: 80 },
  { id: 2, name: 'John Doe', age: 26, status: 'single', visits: 120 }
]);

<Table data={data}>
  <Table.Column label="ID" key="id">
    {({ data }) => <span>{ data.id }</span>}
  </Table.Column>
  <Table.Column label="Name" key="name" />
  <Table.Column label="Info" key="info">
    <Table.Column label="Age" key="age">
      {({ data }) => <span>{ data.age } years</span>}
    </Table.Column>
    <Table.Column label="Status" key="status" />
  </Table.Column>
  <Table.Column label="Visits" key="visits" accessor={({ visits }) => visits + ' of 200'} />
</Table>

Examples

Basic Table

Table is composed of columns defined with Table.Column component. A column should have a label (header) and an accessor (value getter for cells in the column).

The label can be declared with label prop for string headers and renderLabel for custom headers.

The accessor field can be a property name or a getter function. Also, if accessor property name is same as key, it can be omitted.

const [data] = useState([
  { id: 1, name: 'Jane Doe', createdAt: 1557208976092 },
  { id: 2, name: 'John Doe', createdAt: 1557208976092 }
]);

/* Just specify the columns. */
<Table data={data}>
  <Table.Column key="id" label="ID" />
  <Table.Column key="full-name" label="Name" accessor="name" />
  <Table.Column key="created-at" label="Created At" accessor={item => new Date(item.createdAt).toLocaleString()} />
</Table>

Fixed Column Table

A table can have any number of fixed columns on left.

const [data] = useState(Array(20).fill({ id: 1, name: 'Jane Doe', }));

<Table data={data} style={{ height: 320 }}>
  <Table.Column key="info" fixed>
    <Table.Column key="id" label="ID" />
    <Table.Column key="name" label="Name" />
  </Table.Column>

  {
    Array(14) // create empty array of length 14
      .fill(null) // fill it with null so we map over it
      .map(
        (_, index) => (
          // return a column for every index
          <Table.Column
            key={`day-${index}`}
            label={`Day ${index}`}
            accessor={() => Math.random() > 0.25 ? '✅' : '❌'}
          />
        )
      )
  }

  <Table.Column key="actions" fixed="end">
    {() => (<Button>view</Button>)}
  </Table.Column>
</Table>

Sortable Column Table

Just mark a column sortable and sorting handles would appear on the column header.

const [data] = useState([
  { id: 1, name: 'John Doe' },
  { id: 2, name: 'Jane Doe' },
]);

<Table data={data}>
  <Table.Column key="id" label="ID" sortable/>
  <Table.Column key="full-name" label="Name" accessor="name" sortable />
</Table>

Filterable Column Table

Just mark a column sortable and sorting handles would appear on the column header.

To use filters, value field in the filter data should match the exact display data of that column. Use onFilter/onSort props for any other use case. Eg: in below table, value field from the filter data will be matched to the name field from the table data.

const [data] = useState([
  { id: 1, name: 'John Doe' },
  { id: 2, name: 'Jane Doe' },
  { id: 3, name: 'Jane Doe' },
]);

const [names] = useState([
  { label: 'Alice', value: 'Alice Doe' },
  { label: 'Bob', value: 'Bob Doe' },
  { label: 'Jane', value: 'Jane Doe' },
]);

<Table data={data}>
  <Table.Filter>
    <Table.Column key="id" label="ID"/>
  </Table.Filter>

  <Table.Filter options={names}>
    <Table.Column key="name" label="Name" accessor="name" />
  </Table.Filter>
</Table>

Very Large Table

Use <Table virtualized>.

const [data] = useState(
  Array(1000).fill(0).map((_, id) => ({ id: id + 1, firstName: "Jane", lastName: "Doe" }))
);

<div style={{ height: 300, minWidth: 600 }}>
 <Table virtualized data={data}>
   {/* Table Configuration */}
  <Table.Column key="id" label="ID" fixed>
    {({ data }) => <div>{data.id}</div>}
  </Table.Column>
  <Table.Column key="name" label="Name" fixed>
  <Table.Column key="firstName" label="First Name" minWidth={120}>
      {({ data }) => <div>{data.firstName}</div>}
    </Table.Column>
  <Table.Column key="lastName" label="Last Name" minWidth={120}>
    {({ data }) => <div>{data.lastName}</div>}
  </Table.Column>
  </Table.Column>

  {Array(20).fill(0).map((_, group) => (
    <Table.Column key={'group' + group} label={`Group (${group + 1})`} minWidth={100}>
      {
        Array(50).fill(0).map((_, index) => (
          <Table.Column key={`group-${group}-column-${index}`} label={`Column ${index + 1}`} minWidth={120}>
            {({ data }) => <div>Sunil</div>}
          </Table.Column>
        ))
      }
    </Table.Column>
  ))}

  <Table.Column key="options" label=" " fixed="end">
    {() => <Icon name={EllipsisVSolid} />}
  </Table.Column>

  {/* Table Customization */}
  <Table.Row selector={index => index % 2}>
    {({ children, style,  rowId }) => <Table.TR key={rowId} style={{ ...style, color: 'red' }}>{children}</Table.TR>}
  </Table.Row>
 </Table>
</div>
const [data] = useState(
  Array(100).fill(0).map((_, id) => ({ id: id + 1, firstName: "Jane", lastName: "Doe" }))
);

<div style={{ height: 'auto' }}>
  <Table virtualized data={data} scrollMode="window">
   {/* Table Configuration */}
  <Table.Column key="id" label="ID" fixed>
    {({ data }) => <div>{data.id}</div>}
  </Table.Column>
  <Table.Column key="name" label="Name" fixed>
  <Table.Column key="firstName" label="First Name" minWidth={120}>
      {({ data }) => <div>{data.firstName}</div>}
    </Table.Column>
  <Table.Column key="lastName" label="Last Name" minWidth={120}>
    {({ data }) => <div>{data.lastName}</div>}
  </Table.Column>
  </Table.Column>

  {Array(10).fill(0).map((_, group) => (
    <Table.Column key={'group' + group} label={`Group (${group + 1})`} minWidth={100}>
      {
        Array(5).fill(0).map((_, index) => (
          <Table.Column key={`group-${group}-column-${index}`} label={`Column ${index + 1}`} minWidth={120}>
            {({ data }) => <div>{data.lastName}</div>}
          </Table.Column>
        ))
      }
    </Table.Column>
  ))}

  <Table.Column key="options" label=" " fixed="end">
    {() => <Icon name={EllipsisVSolid} />}
  </Table.Column>

  {/* Table Customization */}
  <Table.Row selector={index => index % 2}>
    {({ children, style,  rowId }) => <Table.TR key={rowId} style={{ ...style, color: 'red' }}>{children}</Table.TR>}
  </Table.Row>
</Table>
</div>

Sub-components

Table.Column

const [data] = useState([
  { name: 'Jane Doe' },
  { name: 'John Doe' }
]);

<Table data={data}>
  {/* Table.Column should be direct child of Table or Table.Column. */}
  <Table.Column label="Name" key="name" />
</Table>

Table.Filter

const [data] = useState(Array(10).fill(null).map((_, value) => ({ value })));

<Table data={data}>
  <Table.Filter>
    <Table.Column key="value" label="Value" minWidth={200} />
  </Table.Filter>
</Table>

Table.Row

const [data] = useState([
  { name: 'Alice' },
  { name: 'Bob' },
  { name: 'Charlie' },
  { name: 'Dave' },
  { name: 'Eve' },
  { name: 'Frank' },
  { name: 'Grimes' },
  { name: 'Homer' },
  { name: 'Illinois' },
  { name: 'Jake' },
]);

<Table data={data}>
  <Table.Column label="Name" key="name" />

  <Table.Row selector={4}>
    {({ children, style }) => (
      <Table.TR style={{ ...style, color: 'red' }}>{children}</Table.TR>
    )}
  </Table.Row>

  <Table.Row selector={index => index % 2 === 1}>
    {({ children, style }) => (
      <Table.TR style={{ ...style, color: 'blue' }}>{children}</Table.TR>
    )}
  </Table.Row>

  <Table.Row>
    {({ children, style }) => (
      <Table.TR style={{ ...style, color: 'green' }}>{children}</Table.TR>
    )}
  </Table.Row>
</Table>