Skip to content

Table (old)

WARNING

🚨 Library @semcore/table is deprecated. Use new library @semcore/data-table. It is based on the CSS grid and doesn't use native tables.

Table with accordion

Example of the table with Accordion.

tsx
import Accordion from '@semcore/accordion';
import { Box } from '@semcore/flex-box';
import Table from '@semcore/table';
import React from 'react';

const Demo = () => (
  <Table>
    <Table.Head>
      <Table.Row>
        {Object.keys(data[0]).map((name) => (
          <Table.CellHead key={name}>{name}</Table.CellHead>
        ))}
      </Table.Row>
    </Table.Head>
    <Table.Body>
      <Accordion>
        {data.map((item, index) => (
          <Accordion.Item value={index} key={index}>
            <Accordion.Item.Toggle tag={Table.Row}>
              {Object.values(item).map((value, ind) => (
                <Table.Cell
                  key={value}
                  style={ind === 0 ? { display: 'flex', alignItems: 'center' } : {}}
                >
                  {ind === 0 && <Accordion.Item.Chevron color='icon-secondary-neutral' mr={2} />}
                  {value}
                </Table.Cell>
              ))}
            </Accordion.Item.Toggle>
            <Accordion.Item.Collapse>
              <Box p='12px 32px'>{`Section ${index + 1}`}</Box>
            </Accordion.Item.Collapse>
          </Accordion.Item>
        ))}
      </Accordion>
    </Table.Body>
  </Table>
);

const data = [
  {
    keyword: 'ebay buy',
    kd: '77.8',
    cpc: '$1.25',
    vol: '32,500,000',
  },
  {
    keyword: 'www.ebay.com',
    kd: '11.2',
    cpc: '$3.4',
    vol: '65,457,920',
  },
  {
    keyword: 'www.ebay.com',
    kd: '10',
    cpc: '$0.65',
    vol: '47,354,640',
  },
  {
    keyword: 'ebay buy',
    kd: '-',
    cpc: '$0',
    vol: 'n/a',
  },
  {
    keyword: 'ebay buy',
    kd: '75.89',
    cpc: '$0',
    vol: '21,644,290',
  },
];

export default Demo;

Table with fixed header

tsx
import Checkbox from '@semcore/checkbox';
import Link from '@semcore/link';
import ScrollArea from '@semcore/scroll-area';
import Spin from '@semcore/spin';
import Table from '@semcore/table';
import { Hint } from '@semcore/tooltip';
import { Text } from '@semcore/typography';
import React from 'react';

function shuffle(a) {
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

let data = [
  {
    'keyword': 'ebay buy',
    'kd': '77.8',
    'cpc': '$1.25',
    'vol': '32,500,000',
    'diff': 0,
    'traffic': '< 0.01',
    'url': 'https://ebay.com',
    'last update': new Intl.DateTimeFormat('en-US', { year: 'numeric', era: 'long' }).format(
      new Date('2019/11/12'),
    ),
  },
  {
    'keyword': 'www.ebay.com',
    'kd': '11.2',
    'cpc': '$3.4',
    'vol': '65,457,920',
    'diff': 0,
    'traffic': '< 0.01',
    'url': 'https://ebay.com',
    'last update': new Intl.DateTimeFormat('en-US', { year: 'numeric', era: 'long' }).format(
      new Date('2019/11/12'),
    ),
  },
  {
    'keyword': 'www.ebay.com',
    'kd': '10',
    'cpc': '$0.65',
    'vol': '47,354,640',
    'diff': 0,
    'traffic': '< 0.01',
    'url': 'https://ebay.com',
    'last update': new Intl.DateTimeFormat('en-US', { year: 'numeric', era: 'long' }).format(
      new Date('2019/11/12'),
    ),
  },
  {
    keyword: 'ebay buy',
    kd: '-',
    cpc: '$0',
    vol: 'n/a',
    diff: 0,
    traffic: '< 0.01',
    url: 'https://ebay.com',
    last_update: 'n/a',
  },
  {
    keyword: 'ebay buy',
    kd: '75.89',
    cpc: <Spin />,
    vol: <Spin />,
    diff: 0,
    traffic: '< 0.01',
    url: 'https://ebay.com',
    last_update: 'n/a',
  },
];

data.forEach((d) => {
  data = shuffle(data.concat(data));
});

const Demo = () => {
  const [top, setTop] = React.useState(0);
  React.useEffect(() => {
    const header = document.getElementsByTagName('header')[0];
    if (header) {
      setTop(header.offsetHeight);
    }
  }, []);

  return (
    <ScrollArea>
      <ScrollArea.Container>
        <Table>
          <Table.StickyHead top={top} />
          <Table.Head>
            <Table.Row>
              <Table.CellHead align='center' valign='middle' width='50'>
                <Checkbox size='l'>
                  <Checkbox.Value />
                </Checkbox>
              </Table.CellHead>
              <Table.CellHead width='200'>
                <Hint title='Lorem ipsum'>
                  <span tabIndex={0}>
                    Keyword
                    {' '}
                    <Text color='text-secondary'>(1 - 100)</Text>
                  </span>
                </Hint>
              </Table.CellHead>

              {Object.keys(data[0])
                .slice(1)
                .map((name) => (
                  <Table.CellHead key={name} width='200' align='right'>
                    <Hint title='Lorem ipsum'>
                      <span tabIndex={0}>
                        {name.toUpperCase()}
                        {' '}
                        {['kd', 'traffic'].includes(name) && '%'}
                      </span>
                    </Hint>
                  </Table.CellHead>
                ))}
            </Table.Row>
          </Table.Head>
          <Table.Body>
            {data.map((row, i) => (
              <Table.Row key={i} theme={row.kd === '-' ? 'danger' : 'default'}>
                <Table.Cell
                  theme={row.kd === '-' ? false : 'default'}
                  align='center'
                  valign='middle'
                >
                  <Checkbox size='l'>
                    <Checkbox.Value />
                  </Checkbox>
                </Table.Cell>
                <Table.Cell theme={row.kd === '-' ? false : 'default'}>
                  <Link>{row.keyword}</Link>
                </Table.Cell>

                {Object.keys(data[0])
                  .slice(1)
                  .map((name) => (
                    <Table.Cell key={name} align='right' theme={row.kd === '-' ? false : 'default'}>
                      {row[name]}
                    </Table.Cell>
                  ))}
              </Table.Row>
            ))}
          </Table.Body>
        </Table>
      </ScrollArea.Container>
      <ScrollArea.Bar />
    </ScrollArea>
  );
};

export default Demo;

Secondary table

You can use secondary table for compact displaying small amount of data inside widgets.

tsx
import Table from '@semcore/table';
import React from 'react';

const data = [
  {
    keyword: 'ebay buy',
    kd: '77.8',
    cpc: '$1.25',
    vol: 'n/a',
  },
  {
    keyword: 'www.ebay.com',
    kd: '11.2',
    cpc: '$3.4',
    vol: '32,500,000',
  },
  {
    keyword: 'www.ebay.com',
    kd: '10',
    cpc: '$0.65',
    vol: '47,354,640',
  },
  {
    keyword: 'ebay buy',
    kd: '-',
    cpc: '$0',
    vol: '65,457,920',
  },
  {
    keyword: 'ebay buy',
    kd: '75.89',
    cpc: '$0',
    vol: '21,644,290',
  },
];

const Demo = () => (
  <Table use='secondary'>
    <Table.Head>
      <Table.Row theme={false}>
        {Object.keys(data[0])
          .slice(0, -1)
          .map((name) => (
            <Table.CellHead key={name}>{name}</Table.CellHead>
          ))}
        {Object.keys(data[0])
          .slice(-1)
          .map((name) => (
            <Table.CellHead key={name} sorting='asc' active>
              {name}
            </Table.CellHead>
          ))}
      </Table.Row>
    </Table.Head>
    <Table.Body>
      {data.map((row) => (
        <Table.Row key={row['keyword']}>
          {Object.keys(row).map((name) => (
            <Table.Cell key={row[name]}>{row[name]}</Table.Cell>
          ))}
        </Table.Row>
      ))}
    </Table.Body>
  </Table>
);

export default Demo;

Table with skeleton

tsx
import Checkbox from '@semcore/checkbox';
import Skeleton from '@semcore/skeleton';
import Table from '@semcore/table';
import { Hint } from '@semcore/tooltip';
import { Text } from '@semcore/typography';
import React from 'react';

const data = [
  {
    'keyword': 'ebay buy',
    'kd': '77.8',
    'cpc': '$1.25',
    'vol': '32,500,000',
    'diff': 0,
    'traffic': '< 0.01',
    'url': 'https://ebay.com',
    'last update': new Intl.DateTimeFormat('en-US', { year: 'numeric', era: 'long' }).format(
      new Date('2019/11/12'),
    ),
  },
];
const fetchData = () => (
  <Table.Cell>
    <Skeleton height={17}>
      <Skeleton.Text y='5' width='60%' />
    </Skeleton>
  </Table.Cell>
);

const Demo = () => (
  <Table>
    <Table.Head>
      <Table.Row>
        <Table.CellHead align='center' valign='middle'>
          <Checkbox size='l'>
            <Checkbox.Value />
          </Checkbox>
        </Table.CellHead>
        <Table.CellHead>
          <Hint title='Lorem ipsum'>
            <span tabIndex={0}>
              Keyword
              {' '}
              <Text color='text-secondary'>(1 - 100)</Text>
            </span>
          </Hint>
        </Table.CellHead>
        {Object.keys(data[0])
          .slice(1)
          .map((name) => (
            <Table.CellHead key={name}>
              <Hint title='Lorem ipsum'>
                <span tabIndex={0}>
                  {name.toUpperCase()}
                  {' '}
                  {['kd', 'traffic'].includes(name) && '%'}
                </span>
              </Hint>
            </Table.CellHead>
          ))}
      </Table.Row>
    </Table.Head>
    <Table.Body>
      {[...new Array(10)].map((_, index) => (
        <Table.Row key={index} theme={false}>
          {fetchData()}
          {Object.keys(data[0]).map(() => fetchData())}
        </Table.Row>
      ))}
    </Table.Body>
  </Table>
);

export default Demo;

Table with no data

These states for widgets are described in detail in Widget empty state.

tsx
import Table from '@semcore/table';
import { NoData } from '@semcore/widget-empty';
import React from 'react';

const Demo = () => {
  const data = [...new Array(5)];

  return (
    <Table h={300}>
      <Table.Head>
        <Table.Row>
          {data.map((_, indCell) => (
            <Table.CellHead key={indCell}>
              Cell -
              {indCell + 1}
            </Table.CellHead>
          ))}
        </Table.Row>
      </Table.Head>
      <Table.Body>
        <Table.Row theme={false}>
          <Table.Cell colSpan={data.length} pt={10}>
            <NoData
              type='table'
              description='Try selecting a different date or changing your filter settings.'
            />
          </Table.Cell>
        </Table.Row>
      </Table.Body>
    </Table>
  );
};

export default Demo;

Released under the MIT License.

Released under the MIT License.