Skip to content

Commit

Permalink
Custom table elemets (#141)
Browse files Browse the repository at this point in the history
* use tsc instead of ttsc

* allow completely custom TH and TD elements

* fix missing border in container el

* fix table wrapper styling

* change selector

* pass sorting handler

* remove nested check

* add back in ttypescript

* use ttsc for declarations

---------

Co-authored-by: Ciaran Schutte <[email protected]>
  • Loading branch information
ciaranschutte and Ciaran Schutte authored Jan 16, 2024
1 parent 57f105c commit 3ca60cd
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 59 deletions.
32 changes: 16 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@
"react-dom": "^18.2.0",
"react-json-view": "^1.21.3",
"ts-node-dev": "^1.1.8",
"ttypescript": "^1.5.13",
"typescript": "<4.8",
"ttypescript": "^1.5.15",
"typescript": "4.8",
"webpack": "^5.75.0"
},
"prettier": {
Expand Down
98 changes: 58 additions & 40 deletions src/Table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,11 @@ export const Table = <TData extends object>({

return (
<TableContainer className={className}>
<TableContainerInner withFilters={withFilters} withTabs={withTabs}>
<TableContainerInner
withFilters={withFilters}
withTabs={withTabs}
withSideBorders={withSideBorders}
>
<TableStyled withSideBorders={withSideBorders}>
{withHeaders && (
<TableHead>
Expand All @@ -131,48 +135,54 @@ export const Table = <TData extends object>({
{headerGroup.headers.map((header) => {
const canSort = enableSorting && header.column.getCanSort();
const isCustomHeader = header.column.columnDef.meta?.customHeader;
const tableHeaderProps = {
key: header.id,
colSpan: header.colSpan,
width: header.getSize(),
sorted: header.column.getIsSorted(),
getSortingHandler: () => header.column.getToggleSortingHandler(),
canSort,
};

const headerContents = header.isPlaceholder
? null
: flexRender(header.column.columnDef.header, header.getContext());
: flexRender(header.column.columnDef.header, {
...tableHeaderProps,
...header.getContext(),
});

const {
activeTab = '',
handleTabs = () => {},
tabs = [],
} = header.column.columnDef.meta?.columnTabs || {};

return (
<TableHeader
key={header.id}
colSpan={header.colSpan}
width={header.getSize()}
sorted={header.column.getIsSorted()}
canSort={canSort}
>
{!!tabs.length && (
<TableTabs activeTab={activeTab} handleTabs={handleTabs} tabs={tabs} />
)}
<SortButton
canSort={canSort}
onClick={header.column.getToggleSortingHandler()}
>
{isCustomHeader ? (
headerContents
) : (
if (isCustomHeader) {
return headerContents;
} else {
return (
<TableHeader {...tableHeaderProps}>
{!!tabs.length && (
<TableTabs activeTab={activeTab} handleTabs={handleTabs} tabs={tabs} />
)}
<SortButton
canSort={canSort}
onClick={header.column.getToggleSortingHandler()}
>
<TableHeaderWrapper>{headerContents}</TableHeaderWrapper>
</SortButton>
{header.column.getCanResize() && (
<Resizer
onMouseDown={header.getResizeHandler()}
onTouchStart={header.getResizeHandler()}
className={`resizer ${
header.column.getIsResizing() ? 'isResizing' : ''
}`}
/>
)}
</SortButton>
{header.column.getCanResize() && (
<Resizer
onMouseDown={header.getResizeHandler()}
onTouchStart={header.getResizeHandler()}
className={`resizer ${
header.column.getIsResizing() ? 'isResizing' : ''
}`}
/>
)}
</TableHeader>
);
</TableHeader>
);
}
})}
</TableRow>
))}
Expand All @@ -190,14 +200,22 @@ export const Table = <TData extends object>({
>
{row.getVisibleCells().map((cell) => {
const isCustomCell = cell.column.columnDef.meta?.customCell;
const cellContents = flexRender(cell.column.columnDef.cell, cell.getContext());
return (
<TableCell key={cell.id} width={cell.column.getSize()}>
{isCustomCell ? (
cellContents
) : (
<TableCellWrapper>{cellContents}</TableCellWrapper>
)}

const tableCellProps = {
key: cell.id,
width: cell.column.getSize(),
};

const cellContents = flexRender(cell.column.columnDef.cell, {
...tableCellProps,
...cell.getContext(),
});

return isCustomCell ? (
cellContents
) : (
<TableCell {...tableCellProps}>
<TableCellWrapper>{cellContents}</TableCellWrapper>
</TableCell>
);
})}
Expand Down
27 changes: 26 additions & 1 deletion src/Table/styled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,40 @@ export const TableContainer = styled(TableContainerComp, {
background: ${COLORS.BACKGROUND};
`;

/*
* stop cells from having overlapping border if we have side borders on our container
*/
const sideBordersStyle = css`
border-right: 1px solid ${colors.grey_2};
border-left: 1px solid ${colors.grey_2};
table,
tr td:first-of-type,
tr th:first-of-type {
border-left: none;
}
table,
tr td:last-of-type,
tr th:last-of-type {
border-right: none;
}
`;

const TableContainerInnerComp = (
props: React.PropsWithChildren<{ className?: string; withFilters?: boolean; withTabs?: boolean }>,
props: React.PropsWithChildren<{
className?: string;
withFilters?: boolean;
withTabs?: boolean;
withSideBorders?: boolean;
}>,
) => <div {...props} className={clsx(TABLE_CLASSES.TABLE_CONTAINER_INNER, props.className)} />;
export const TableContainerInner = styled(TableContainerInnerComp, {
shouldForwardProp: (prop) => isPropValid(prop),
})`
width: 100%;
max-width: 100%;
overflow-x: auto;
${(props) => props.withSideBorders && sideBordersStyle};
${(props) =>
props.withFilters &&
`
Expand Down

0 comments on commit 3ca60cd

Please sign in to comment.