-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Port minimalist table from design-system
- Loading branch information
1 parent
f3ae141
commit a229591
Showing
5 changed files
with
250 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import React, { useState } from 'react'; | ||
import { StoryFn, Meta } from '@storybook/react'; | ||
import { Badge, Switch } from '@mantine/core'; | ||
|
||
import { Table } from './Table'; | ||
import { ColumnDef } from '@tanstack/react-table'; | ||
|
||
export default { | ||
title: 'Components/Table', | ||
component: Table, | ||
argTypes: { | ||
data: { | ||
control: false, | ||
}, | ||
columns: { | ||
control: false, | ||
}, | ||
}, | ||
} as Meta<typeof Table>; | ||
|
||
const SwitchCell = (props) => { | ||
const [status, setStatus] = useState(props.status); | ||
const switchHandler = () => { | ||
setStatus((prev) => (prev === 'Enabled' ? 'Disabled' : 'Enabled')); | ||
}; | ||
|
||
return <Switch label={status} onChange={switchHandler} checked={status === 'Enabled'} />; | ||
}; | ||
|
||
const BadgeCell = (props) => { | ||
return ( | ||
<Badge variant="outline" size="md" radius="xs"> | ||
{props.getValue()} | ||
</Badge> | ||
); | ||
}; | ||
|
||
interface IExampleData { | ||
name: string; | ||
category: string; | ||
creationDate: string; | ||
status: string; | ||
} | ||
|
||
const columns: ColumnDef<IExampleData>[] = [ | ||
{ accessorKey: 'name', header: 'Name' }, | ||
{ accessorKey: 'category', header: 'Category', cell: BadgeCell }, | ||
{ accessorKey: 'creationDate', header: 'Date Created' }, | ||
{ accessorKey: 'status', header: 'Status', cell: SwitchCell }, | ||
]; | ||
|
||
const data: IExampleData[] = [ | ||
{ name: 'Great', category: 'Fun', status: 'Disabled', creationDate: '01/01/2021 16:36' }, | ||
{ name: 'Whats up?', category: 'Done', status: 'Enabled', creationDate: '01/01/2021 16:36' }, | ||
]; | ||
|
||
const Template: StoryFn<typeof Table> = ({ ...args }) => <Table columns={columns} data={data} {...args} />; | ||
|
||
export const PrimaryUse = Template.bind({}); | ||
PrimaryUse.args = {}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { type TableStylesNames } from '@mantine/core'; | ||
import { css } from '../../../styled-system/css'; | ||
|
||
const tableStyles: Partial<Record<TableStylesNames, string>> = { | ||
tr: css({ | ||
'& td': { | ||
textOverflow: 'ellipsis', | ||
}, | ||
}), | ||
table: css({ | ||
borderCollapse: 'collapse', | ||
borderSpacingX: '125', | ||
textStyle: 'text.main', | ||
'& tr td:first-of-type': { | ||
pl: '200', | ||
pr: '200', | ||
}, | ||
'& tr th:first-of-type': { | ||
pl: '200', | ||
pr: '200', | ||
}, | ||
'& tr td:last-child': { | ||
pr: '200', | ||
}, | ||
'& tr th:last-child': { | ||
pr: '200', | ||
}, | ||
'& thead tr': { | ||
borderBottom: 'solid', | ||
borderColor: 'table.header.border', | ||
}, | ||
'& thead tr th': { | ||
fontWeight: 'regular', | ||
// height: '17px', | ||
textAlign: 'left', | ||
color: 'typography.text.tertiary', | ||
borderBottom: 'none', | ||
borderSpacing: '0', | ||
pb: '100', | ||
}, | ||
'& tbody tr td': { | ||
// TODO: replace with token value | ||
maxWidth: '[100px]', | ||
// TODO: replace with token value | ||
height: '[80px]', | ||
|
||
color: 'typography.text.main', | ||
borderBottom: 'solid', | ||
borderColor: 'table.row.border', | ||
}, | ||
'& tbody tr[data-disabled="true"]:hover': { | ||
cursor: 'default', | ||
}, | ||
'& tbody tr[data-disabled="false"]:hover': { | ||
cursor: 'pointer', | ||
}, | ||
'& tbody tr:last-of-type td': { | ||
borderBottom: 'solid', | ||
borderColor: 'table.bottom.border', | ||
}, | ||
_hover: { | ||
'& tbody tr:hover': { | ||
bg: 'table.row.surface.hover', | ||
}, | ||
}, | ||
}), | ||
}; | ||
|
||
export default tableStyles; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { Table as ExternalTable } from '@mantine/core'; | ||
import { flexRender, getCoreRowModel, Row, useReactTable } from '@tanstack/react-table'; | ||
import React, { useMemo } from 'react'; | ||
import { CoreProps } from 'src/types'; | ||
|
||
import classes from './Table.styles'; | ||
|
||
export type IRow<T extends object = {}> = Row<T>; | ||
|
||
export interface ITableProps<T extends object> extends CoreProps { | ||
columns?: any[]; | ||
data?: T[]; | ||
isLoading?: boolean; | ||
pagination?: any; | ||
noDataPlaceholder?: React.ReactNode; | ||
loadingItems?: number; | ||
hasMore?: boolean; | ||
onRowClick?: (row: Row<T>) => void; | ||
onRowSelect?: (row: Row<T>) => void; | ||
} | ||
|
||
/** | ||
* Table component | ||
* | ||
*/ | ||
export function Table<T extends object>({ | ||
columns: userColumns, | ||
data: userData, | ||
isLoading = false, | ||
noDataPlaceholder, | ||
loadingItems = 10, | ||
onRowClick, | ||
onRowSelect, | ||
...props | ||
}: ITableProps<T>) { | ||
const columns = useMemo(() => userColumns?.map((col) => ({ ...col })), [userColumns]); | ||
const data = useMemo(() => (userData || [])?.map((row) => ({ ...row })), [userData]); | ||
const fakeData = useMemo(() => Array.from({ length: loadingItems }).map((_, index) => ({ index })), [loadingItems]); | ||
|
||
const table = useReactTable<T>({ | ||
columns, | ||
data: isLoading ? (fakeData as T[]) : data, | ||
getCoreRowModel: getCoreRowModel(), | ||
// FIXME: remove this | ||
debugTable: true, | ||
}); | ||
|
||
return ( | ||
<ExternalTable classNames={classes} highlightOnHover {...props}> | ||
<thead> | ||
{table.getHeaderGroups().map((headerGroup, i) => { | ||
return ( | ||
<tr key={headerGroup.id} {...headerGroup}> | ||
{headerGroup.headers.map((header) => { | ||
return ( | ||
<th key={header.id} {...header}> | ||
{flexRender(header.column.columnDef.header, header.getContext())} | ||
</th> | ||
); | ||
})} | ||
</tr> | ||
); | ||
})} | ||
</thead> | ||
<tbody> | ||
{table.getRowModel().rows.map((row) => { | ||
return ( | ||
<tr | ||
key={row.id} | ||
onClick={(e) => { | ||
e.stopPropagation(); | ||
if (!isLoading && onRowClick) { | ||
onRowClick(row); | ||
} | ||
}} | ||
{...row} | ||
className={classes.tr} | ||
data-disabled={isLoading || !onRowClick} | ||
> | ||
{row.getVisibleCells().map((cell) => { | ||
return ( | ||
<td key={cell.id} {...cell}> | ||
{flexRender(cell.column.columnDef.cell, cell.getContext())} | ||
</td> | ||
); | ||
})} | ||
</tr> | ||
); | ||
})} | ||
</tbody> | ||
</ExternalTable> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { Table } from './Table'; | ||
export type { IRow, ITableProps } from './Table'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters