Skip to content

Commit

Permalink
feat: implement basic functionality of table component
Browse files Browse the repository at this point in the history
  • Loading branch information
JordanMooree committed Aug 11, 2022
1 parent 10d626d commit b6bd15b
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 0 deletions.
15 changes: 15 additions & 0 deletions tools/ui-components/src/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@
@apply underline;
}
}
@layer components {
/* Table component */
.bordered > thead > tr > th,
.bordered > tbody > tr > th,
.bordered > tfoot > tr > th,
.bordered > thead > tr > td,
.bordered > tbody > tr > td,
.bordered > tfoot > tr > td {
border: 1px solid #ddd;
}
.table-hover > tbody > tr:hover {
background-color: #f5f5f5;
/* color: black; -- Used for storybook use case only */
}
}

@tailwind components;
@tailwind utilities;
3 changes: 3 additions & 0 deletions tools/ui-components/src/table/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

export { Table } from './table';
export type { TableProps } from './types';
87 changes: 87 additions & 0 deletions tools/ui-components/src/table/table.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React from 'react';
import { Story } from '@storybook/react';
import { Table, TableProps } from '.';

const exampleTable = (
<>
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Last Name</th>
<th>Username</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<td>2</td>
<td>John</td>
<td>Loos</td>
<td>@mlos</td>
</tr>
<tr>
<td>3</td>
<td>Joe</td>
<td>Kot</td>
<td>@mko</td>
</tr>
</tbody>
</>
);

const story = {
title: 'Example/Table',
component: Table,
parameters: {
controls: {
include: ['variant', 'size', 'bordered', 'borderless', 'hover', 'striped']
}
},
argTypes: {
variant: {
options: ['light', 'dark']
},
bordered: {
options: [true, false],
control: { type: 'radio' }
},
striped: {
options: [true, false],
control: { type: 'radio' }
},
hover: {
options: [true, false],
control: { type: 'radio' }
},
borderless: {
options: [true, false],
control: { type: 'radio'},
// Used to avoid conflict with borders
if: {arg: 'bordered', truthy: false}
},
size: {
options: ['small', 'medium', 'large']
}

}

};

const Template: Story<TableProps> = args => (
<Table {...args}>{exampleTable}</Table>
);
export const Default = Template.bind({});
Default.args = {
// default props go here
bordered: true,
size: 'medium',
variant: 'light'
};

export default story;
10 changes: 10 additions & 0 deletions tools/ui-components/src/table/table.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

import { Table } from '.';

describe('<Table />', () => {
it('should render correctly', () => {});
});
59 changes: 59 additions & 0 deletions tools/ui-components/src/table/table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import '../../../../client/src/components/layouts/global.css'

import { TableProps, TableVariant } from './types';

const defaultClassNames = ['table','table-auto', 'w-full', 'border-collapse',
'text-left', 'bg-transparent'];
const MAX_MOBILE_WIDTH = 767;

const computeWindowSize = window.innerWidth <= MAX_MOBILE_WIDTH

const variantClasses: Record<TableVariant, string> = {
light: 'bg-light-theme-background',
dark: 'bg-dark-theme-background text-gray-0'
}

const computeClassNames = (size: string) => {
switch (size) {
case 'large':
return 'text-lg'
case 'small':
return 'text-sm'
// default is medium
default:
return 'text-md'
}
}

export const Table = React.forwardRef<HTMLTableElement, TableProps>(
(
{ borderless, bordered, className, hover, striped, responsive, variant, size, ...props },
ref
) => {
props.cellPadding = 10 // Default cell padding for visual clarity in Storybook

if (borderless && bordered) bordered = false;

const borderClass = bordered ? "bordered" : ""
const stripedClass = striped ? "table-striped" : ""
const hoverClass = hover ? "table-hover" : ""

const classes = [...defaultClassNames, borderClass, stripedClass, computeClassNames(size || ''), hoverClass].join(' ');


const table = <table {...props} ref={ref} className={classes}/>;

if (responsive) {
let responsiveClass = computeWindowSize ? 'sm' : 'lg';
return <div className={responsiveClass}>{table}</div>
}

// For storybook use cases. Table should remain transparent to the background color
// if (variant == 'light') {
// return <div className={variantClasses[variant]}>{table}</div>
// } else return <div className={variantClasses[variant]}>{table}</div>

return table;
}
);
14 changes: 14 additions & 0 deletions tools/ui-components/src/table/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from "react";

export type TableVariant = 'light' | 'dark';

export interface TableProps extends React.TableHTMLAttributes<HTMLTableElement> {
bordered?: boolean;
borderless?: boolean;
className?: string;
hover?: boolean;
size?: string;
striped?: boolean | string;
variant?: TableVariant;
responsive?: boolean;
}

0 comments on commit b6bd15b

Please sign in to comment.