---
title: Table
category: General
---

```jsx live
const data = generateFakeData(
  (faker) => ({
    id: faker.random.uuid(),
    avatar: faker.image.avatar(),
    firstName: faker.name.firstName(),
    lastName: faker.name.lastName(),
    age: faker.random.number(),
  }),
  10
)
render(
  <Table
    data={data}
    columns={[
      {
        width: 54,
        cell: (row, state) => {
          return <Avatar source={row.avatar} />
        },
      },
      {
        header: 'First Name',
        cell: 'firstName',
      },
      {
        header: 'Last Name',
        cell: 'lastName',
      },
    ]}
  />
)
```

```jsx live
const data = generateFakeData(
  (faker) => ({
    id: faker.random.uuid(),
    title: faker.name.title(),
    bpm: faker.random.number(),
    subRow: generateFakeData(
      (faker) => ({
        id: faker.random.uuid(),
        title: faker.name.title(),
        bpm: faker.random.number(),
      }),
      3
    ),
  }),
  10
)
render(
  <Table
    data={data}
    columns={[
      {
        header: <Table.CheckboxCell />,
        cell: (props) => <Table.CheckboxCell />,
        subRowCell: null,
      },
      {
        header: 'Title',
        cell: 'title',
      },
      {
        header: 'BPM',
        cell: 'bpm',
      },
    ]}
    subRowData={(rowData) => rowData.subRow}
  />
)
```

```jsx live
function getHiddenColumnIdsFromAPI() {
  const localHiddenColumnIds =
    typeof window === 'undefined'
      ? null
      : localStorage.getItem('localHiddenColumnIds')
  return localHiddenColumnIds ? JSON.parse(localHiddenColumnIds) : []
}

class StatefulCell extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      isEditing: false,
    }
  }
  render() {
    return (
      <Box>
        {this.state.isEditing ? (
          <Select onChange={() => this.setState({ isEditing: false })}>
            <Select.Option value="1">Value 1</Select.Option>
          </Select>
        ) : (
          <Text
            wrap={false}
            truncate
            onClick={() => this.setState({ isEditing: true })}
          >
            {this.props.name}
          </Text>
        )}
      </Box>
    )
  }
}

class TableExample extends React.Component {
  constructor(props) {
    super(props)

    const initialAmount = 10

    this.state = {
      data: this.getData(initialAmount),
      amount: initialAmount,
      compactHeader: false,
      hiddenColumnIds: getHiddenColumnIdsFromAPI(),
    }

    this.hideColumns = ({ hiddenColumnIds }) => {
      this.setState({ hiddenColumnIds })
      localStorage.setItem(
        'localHiddenColumnIds',
        JSON.stringify(hiddenColumnIds)
      )
    }

    this.loadNewData = () => {
      this.setState({ data: this.getData(this.state.amount) })
    }
  }

  getColumns() {
    return [
      {
        id: 'avatar',
        width: 54,
        cell: (row, state) => {
          return <Avatar source={row.avatar} />
        },
        sticky: true,
      },
      {
        id: 'fullName',
        header: 'Full Name',
        cell: (row) => (
          <Text wrap={false}>{row.firstName + ' ' + row.lastName}</Text>
        ),
        alwaysVisible: true,
        // sticky: true,
      },
      {
        id: 'firstName',
        header: 'First Name',
        cell: 'firstName',
        // width: 90,
        // vertical: true,
      },
      {
        id: 'lastName',
        sortable: true,
        header: 'Last Name',
        cell: 'lastName',
      },
      {
        id: 'company',
        header: 'Company',
        cell: (row) => {
          return <StatefulCell name={row.companyName} />
        },
        width: 200,
        truncate: true,
      },
      {
        id: 'age',
        width: 64,
        justifyContent: 'center',
        marginLeft: 'auto',
        position: 'sticky',
        right: 0,
        header: <Icon name="person" />,
        label: 'Age',
        cell: 'age',
      },
    ]
  }

  getData(amount) {
    return generateFakeData(
      (faker) => ({
        id: faker.random.uuid(),
        avatar: faker.image.avatar(),
        firstName: faker.name.firstName(),
        lastName: faker.name.lastName(),
        companyName: faker.company.companyName(),
        age: faker.random.number(),
      }),
      amount
    )
  }

  render() {
    const { amount, data, hiddenColumnIds } = this.state
    const columns = this.getColumns()
    return (
      <Card>
        <StackView axis="horizontal" alignment="center" padding={2}>
          <Heading level={3}>{data.length} Results</Heading>
          <StackView
            axis="horizontal"
            alignment="center"
            marginLeft="auto"
            spacing={1}
          >
            <Group>
              <Input
                type="number"
                min={1}
                autoWidth
                value={amount}
                onChange={(event) =>
                  this.setState({ amount: +event.target.value })
                }
              />
              <Button
                title="Reload Data"
                variant="outline"
                onClick={this.loadNewData}
              />
            </Group>
            <Button
              title="Compact header"
              iconRight={
                this.state.compactHeader ? { name: 'checkmark' } : undefined
              }
              variant="outline"
              onClick={() =>
                this.setState({ compactHeader: !this.state.compactHeader })
              }
            />
            <Table.ColumnPicker
              columns={columns.filter((column) => column.id !== 'avatar')}
              hiddenColumnIds={hiddenColumnIds}
              onChange={this.hideColumns}
            />
          </StackView>
        </StackView>
        <Divider margin={0} />
        <Table
          headerColor="white"
          compactHeader={this.state.compactHeader}
          caption="People in Carlsbad Church"
          data={data}
          columns={columns}
          hiddenColumnIds={hiddenColumnIds}
          getRowLink={(rowData) =>
            `https://google.com/search?q=${rowData.companyName}`
          }
          onRowSort={(data) => this.setState({ data })}
          columnDividers={true}
          rowDividers={true}
          minHeight="auto"
          minRowHeight={4}
        />
      </Card>
    )
  }
}

render(TableExample)
```
