Skip to content

Commit

Permalink
feat: Table component
Browse files Browse the repository at this point in the history
  • Loading branch information
kostasdano committed Apr 9, 2024
1 parent 80a3934 commit 4038386
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/components/Table/Table.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Meta, Canvas, ArgTypes } from '@storybook/blocks';
import Table from './Table';
import * as TableStories from './Table.stories';
import { DisplayColumnStory } from './utils/TableStoryComponents';

<Meta of={TableStories} />

<SectionHeader
title={'Table'}
sections={[
{ title: 'Overview', href: '#overview' },
{ title: 'Props', href: '#table-props' },
{ title: 'Usage', href: '#usage' },
{ title: 'Variants', href: '#variants' },
]}
/>

## Overview

A universal Table component that applies Orfium basic usages.

## Table Props

<ArgTypes of={Table} />

## DisplayColumn Type

<ArgTypes of={DisplayColumnStory} />

<SubsectionHeader title="Variants" />

### Table Sizes

<Canvas of={TableStories.TableSizes} />
27 changes: 27 additions & 0 deletions src/components/Table/Table.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Table from './Table';
import { SimpleData, simpleColumns, simpleData } from './constants';

export default {
title: 'Updated Components/Table/Table',
component: Table,

args: {
rowSize: 'sm',
},
};

export const TableSizes = {
render: (args) => {
const { rowSize } = args;

return <Table<SimpleData> data={simpleData} columns={simpleColumns} rowSize={rowSize} />;
},

name: 'Table Sizes',

parameters: {
controls: {
include: ['rowSize'],
},
},
};
27 changes: 27 additions & 0 deletions src/components/Table/Table.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { SerializedStyles } from '@emotion/react';
import { css } from '@emotion/react';
import type { Theme } from 'theme';

export const tableContainer =
() =>
(theme: Theme): SerializedStyles => {
return css`
display: inline-block;
border: 1px solid ${theme.tokens.colors.get('borderColor.decorative.default')};
border-radius: 4px;
background: ${theme.globals.colors.get('neutral.1')};
`;
};

export const tableStyles = (): SerializedStyles => {
return css`
thead > tr > th:last-child,
tbody > tr > td:last-child {
border-right: none;
}
tbody > tr:last-child > td {
border-bottom: none;
}
`;
};
48 changes: 48 additions & 0 deletions src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { flexRender } from '@tanstack/react-table';
import React from 'react';

import type { TableProps } from '.';
import { TBody, TH, TD, THead, TR } from './components';
import useTable from './hooks/useTable';
import { tableContainer, tableStyles } from './Table.style';

const Table = <TData,>({ data, columns, rowSize = 'sm' }: TableProps<TData>) => {
const table = useTable<TData>({ data, columns });

return (
<div css={tableContainer()}>
<table css={tableStyles()}>
<THead>
{table.getHeaderGroups().map((headerGroup) => (
<TR key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TH key={header.id} colSpan={header.colSpan} rowSize={rowSize}>
{header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext())}
</TH>
))}
</TR>
))}
</THead>
<TBody>
{table.getRowModel().rows.map((row) => {
return (
<TR key={row.id}>
{row.getVisibleCells().map((cell) => {
return (
<TD key={cell.id} rowSize={rowSize}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TD>
);
})}
</TR>
);
})}
</TBody>
</table>
</div>
);
};

export default Table;
22 changes: 22 additions & 0 deletions src/components/Table/constants.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export type SimpleData = {
firstName: string;
lastName: string;
age: string;
job: string;
};

export const simpleColumns = [
{ id: 'firstName', header: 'First Name' },
{ id: 'lastName', header: 'Last Name' },
{ id: 'age', header: 'Age' },
{ id: 'job', header: 'Job' },
];

export const simpleData = [
{ cells: { firstName: 'Rachel', lastName: 'Berry', age: '30', job: 'Fashion Executive' } },
{ cells: { firstName: 'Ross', lastName: 'Geller', age: '32', job: 'Paleontologist' } },
{ cells: { firstName: 'Monica', lastName: 'Geller', age: '31', job: 'Chef' } },
{ cells: { firstName: 'Chandler', lastName: 'Bing', age: '32', job: '?' } },
{ cells: { firstName: 'Joey', lastName: 'Tribbiani', age: '30', job: 'Actor' } },
{ cells: { firstName: 'Phoebe', lastName: 'Buffay', age: '31', job: 'Massage Therapist' } },
];
4 changes: 4 additions & 0 deletions src/components/Table/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export { default } from './Table';
export * from './components';
export * from './hooks';
export * from './types';
27 changes: 27 additions & 0 deletions src/components/Table/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export type TableProps<TData> = {
/** The Columns configuration of the Table */
columns: DisplayColumn[];
/** The Data of the Table */
data: TableData<TData>;
/** Size of Row */
rowSize?: RowSize;
};

export type UseTableProps<TData> = Pick<TableProps<TData>, 'columns' | 'data'>;

/** Columns */

export type DisplayColumn = {
/** The id of the column; must be the same as the column key in the Data type */
id: string;
/** The label of the column on the table */
header: string;
};

/** Rows & Cells */

export type TableData<TData> = {
cells: TData;
}[];

export type RowSize = 'sm' | 'md' | 'lg';

0 comments on commit 4038386

Please sign in to comment.