Skip to content

Commit

Permalink
DApp-1799 blocks/table (#1824)
Browse files Browse the repository at this point in the history
* table in progress

* in progress

* in progress

* table complete

* fixed header route +  reverted changes

* added alignment support
  • Loading branch information
rohitmalhotra1420 authored Aug 23, 2024
1 parent a77f285 commit 17108bc
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 5 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"dependencies": {
"@babel/runtime": "^7.21.0",
"@emotion/react": "^11.8.2",
"@emotion/react": "^11.13.0",
"@emotion/styled": "^11.8.1",
"@ethersproject/abi": "^5.6.0",
"@ethersproject/providers": "^5.6.0",
Expand All @@ -44,6 +44,7 @@
"@reach/combobox": "^0.18.0",
"@reach/tabs": "^0.18.0",
"@reduxjs/toolkit": "^1.7.1",
"@table-library/react-table-library": "^4.1.7",
"@tanstack/react-query": "^5.44.0",
"@tanstack/react-query-devtools": "^5.44.0",
"@testing-library/dom": "^9.0.1",
Expand Down
3 changes: 2 additions & 1 deletion src/blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export { Separator, type SeparatorProps } from './separator';
export { Skeleton, type SkeletonProps } from './skeleton';
export { Select, type SelectProps } from './select';
export { Tabs, type TabsProps, type TabItem } from './tabs';
export { Tag } from './tag';
export { Table, type TableProps } from './table';
export { Tag, type TagProps } from './tag';
export { Text, type TextProps } from './text';
export { Tooltip, type TooltipProps } from './tooltip';
export { TextArea, type TextAreaProps } from './textarea';
Expand Down
175 changes: 175 additions & 0 deletions src/blocks/table/Table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import { FC, useMemo } from 'react';
import {
Table as ReactTable,
Header,
HeaderRow,
Body,
Row,
HeaderCell,
Cell,
} from '@table-library/react-table-library/table';
import { useTheme } from '@table-library/react-table-library/theme';
import styled from 'styled-components';
import { textVariants } from '../text';
import { SurfaceColors } from '../theme/Theme.types';
import { Column, DataSource } from './Table.types';

export type TableProps = {
columns: Column[];
dataSource: DataSource[];
fixedHeader?: boolean;
backgroundColor?: SurfaceColors;
};

const StyledHeaderCell = styled(HeaderCell)<{ headerAlignment?: Column['headerAlignment'] }>`
${({ headerAlignment }) =>
headerAlignment
? `
div {
display: flex;
justify-content: ${headerAlignment};
}
`
: ''}
`;

const StyledRowCell = styled(Cell)<{ cellAlignment?: Column['cellAlignment'] }>`
${({ cellAlignment }) =>
cellAlignment
? `
div {
display: flex;
justify-content: ${cellAlignment};
}
`
: ''}
`;

const Table: FC<TableProps> = ({ backgroundColor = 'surface-secondary', columns, dataSource, fixedHeader = false }) => {
const columnData = useMemo(() => {
const columnWidths = columns.map((col) => col.width || `${100 / columns.length}%`);

const leftRightPositionCSS = columns
.map((col, index) => {
if (col?.fixed == 'left') {
return `
&:nth-of-type(${index + 1}) {
left: ${index === 0 ? '0px' : columnWidths[index]};
};
`;
}
if (col?.fixed == 'right') {
return `
&:nth-of-type(${index + 1}) {
right: ${index + 1 === columns.length ? '0px' : columnWidths[index]};
};
`;
}

return '';
})
.join('');

return {
columnWidthCSS: columnWidths.join(' '),
leftRightPositionCSS,
};
}, [columns]);

const theme = useTheme({
Table: `
--data-table-library_grid-template-columns: ${columnData.columnWidthCSS};
`,
BaseCell: `
${columnData.leftRightPositionCSS}
`,
Cell: `
align-items: center;
align-self: stretch;
border-bottom: var(--border-sm) solid var(--components-table-stroke-default);
color: var(--components-table-text-default);
display: flex;
flex: 1 0 0;
font-family: var(--font-family);
font-size: ${textVariants['bs-semibold'].fontSize};
font-style: ${textVariants['bs-semibold'].fontStyle};
font-weight: ${textVariants['bs-semibold'].fontWeight};
line-height: ${textVariants['bs-semibold'].lineHeight};
gap: var(--spacing-xxs);
height: 56px;
padding: var(--spacing-xxxs);
`,
Row: `
background: var(--${backgroundColor});
`,
HeaderRow: `
background: var(--${backgroundColor});
`,
HeaderCell: `
align-items: center;
color: var(--components-table-text-heading);
display: flex;
font-family: var(--font-family);
font-size: ${textVariants['c-bold'].fontSize};
font-style: ${textVariants['c-bold'].fontStyle};
font-weight: ${textVariants['c-bold'].fontWeight};
line-height: ${textVariants['c-bold'].lineHeight};
padding: var(--spacing-xxs) var(--spacing-xxxs);
gap: 10px;
`,
});

return (
<ReactTable
data={{
nodes: dataSource,
}}
theme={theme}
layout={{ custom: true, horizontalScroll: true, fixedHeader }}
>
{(tableList: DataSource[]) => (
<>
<Header>
<HeaderRow>
{columns.map((column, index) => (
<StyledHeaderCell
headerAlignment={column.headerAlignment}
key={`${column.title}-${index}`}
pinLeft={column?.fixed === 'left'}
pinRight={column?.fixed === 'right'}
>
{column.title}
</StyledHeaderCell>
))}
</HeaderRow>
</Header>

<Body>
{tableList.map((record) => (
<Row
key={record.id}
item={record}
>
{columns.map((column) => {
const cellValue = `${record?.[column.dataIndex] || ''}`;
return (
<StyledRowCell
cellAlignment={column.cellAlignment}
key={`${column.dataIndex}-${record.id}`}
pinLeft={column?.fixed === 'left'}
pinRight={column?.fixed === 'right'}
>
{column.render ? column.render(cellValue, record) : cellValue}
</StyledRowCell>
);
})}
</Row>
))}
</Body>
</>
)}
</ReactTable>
);
};

export { Table };
16 changes: 16 additions & 0 deletions src/blocks/table/Table.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { CSSProperties, ReactNode } from 'react';

export type Column = {
title: string;
dataIndex: string;
cellAlignment?: CSSProperties['justifyContent'];
headerAlignment?: CSSProperties['justifyContent'];
render?: (text: string, record: any) => ReactNode;
width?: string;
fixed?: 'left' | 'right';
};

export type DataSource = {
id: string;
[key: string]: any;
};
1 change: 1 addition & 0 deletions src/blocks/table/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Table';
4 changes: 4 additions & 0 deletions src/blocks/theme/colors/colors.semantics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { textAreaSemantics } from '../semantics/semantics.textarea';
import { toastSemantics } from '../semantics/semantics.toast';
import { tooltipSemantics } from '../semantics/semantics.tooltip';
import { spinnerSemantics } from '../semantics/semantics.spinner';
import { tableSemantics } from '../semantics/semantics.table';

// TODO: find a better way to do this in future
type SemanticKeys = {
Expand All @@ -46,6 +47,7 @@ type SemanticKeys = {
surface: 'surface';
stroke: 'stroke';
skeleton: 'components-skeleton-loader';
table: 'components-table';
tag: 'components-tag';
text: 'text';
textArea: 'components-textarea';
Expand Down Expand Up @@ -74,6 +76,7 @@ export const semanticKeys: SemanticKeys = {
surface: 'surface',
stroke: 'stroke',
skeleton: 'components-skeleton-loader',
table: 'components-table',
tag: 'components-tag',
text: 'text',
textArea: 'components-textarea',
Expand Down Expand Up @@ -102,6 +105,7 @@ export const colorSemantics = {
[semanticKeys.surface]: surfaceSemantics,
[semanticKeys.stroke]: strokeSemantics,
[semanticKeys.skeleton]: skeletonSemantics,
[semanticKeys.table]: tableSemantics,
[semanticKeys.tag]: tagSemantics,
[semanticKeys.text]: textSemantics,
[semanticKeys.textArea]: textAreaSemantics,
Expand Down
14 changes: 14 additions & 0 deletions src/blocks/theme/semantics/semantics.table.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { iconSemantics } from './semantics.icon';
import { strokeSemantics } from './semantics.stroke';
import { textSemantics } from './semantics.text';

export const tableSemantics = {
'stroke-default': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark },

'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark },
'text-heading': { light: textSemantics['tertiary'].light, dark: textSemantics['tertiary'].dark },
'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark },

'icon-default': { light: iconSemantics['primary'].light, dark: iconSemantics['primary'].dark },
'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark },
};
2 changes: 1 addition & 1 deletion src/structure/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ function Header({ isDarkMode, darkModeToggle }) {
justify="flex-start"
flex="0"
>
<Link to="/channels">
<Link to="/welcome">
<Logo src={!isDarkMode ? PushLogoLight : PushLogoDark} />
</Link>
</RightBarDesktop>
Expand Down
50 changes: 48 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ __metadata:
languageName: node
linkType: hard

"@emotion/react@npm:^11.8.2":
"@emotion/react@npm:^11.13.0":
version: 11.13.0
resolution: "@emotion/react@npm:11.13.0"
dependencies:
Expand Down Expand Up @@ -6241,6 +6241,21 @@ __metadata:
languageName: node
linkType: hard

"@table-library/react-table-library@npm:^4.1.7":
version: 4.1.7
resolution: "@table-library/react-table-library@npm:4.1.7"
dependencies:
clsx: "npm:1.1.1"
react-virtualized-auto-sizer: "npm:1.0.7"
react-window: "npm:1.8.7"
peerDependencies:
"@emotion/react": ">= 11"
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: 10/14fba2fdfd09d25d6e8321874b934ce250814e7bdb8a5c5dc627dbcd61f5d2c5d1d5ae3a52ce4036a1f28fb883ecec88ed9bd4441b2756258fe05dfce2d4fd15
languageName: node
linkType: hard

"@tanstack/query-async-storage-persister@npm:4.29.23":
version: 4.29.23
resolution: "@tanstack/query-async-storage-persister@npm:4.29.23"
Expand Down Expand Up @@ -9964,6 +9979,13 @@ __metadata:
languageName: node
linkType: hard

"clsx@npm:1.1.1":
version: 1.1.1
resolution: "clsx@npm:1.1.1"
checksum: 10/ff052650329773b9b245177305fc4c4dc3129f7b2be84af4f58dc5defa99538c61d4207be7419405a5f8f3d92007c954f4daba5a7b74e563d5de71c28c830063
languageName: node
linkType: hard

"clsx@npm:2.1.0":
version: 2.1.0
resolution: "clsx@npm:2.1.0"
Expand Down Expand Up @@ -18216,7 +18238,7 @@ __metadata:
"@3id/connect": "npm:0.4.1"
"@babel/runtime": "npm:^7.21.0"
"@ceramicnetwork/ceramic-core": "npm:0.12.4"
"@emotion/react": "npm:^11.8.2"
"@emotion/react": "npm:^11.13.0"
"@emotion/styled": "npm:^11.8.1"
"@ethersproject/abi": "npm:^5.6.0"
"@ethersproject/providers": "npm:^5.6.0"
Expand All @@ -18236,6 +18258,7 @@ __metadata:
"@reach/combobox": "npm:^0.18.0"
"@reach/tabs": "npm:^0.18.0"
"@reduxjs/toolkit": "npm:^1.7.1"
"@table-library/react-table-library": "npm:^4.1.7"
"@tanstack/react-query": "npm:^5.44.0"
"@tanstack/react-query-devtools": "npm:^5.44.0"
"@testing-library/dom": "npm:^9.0.1"
Expand Down Expand Up @@ -19195,6 +19218,16 @@ __metadata:
languageName: node
linkType: hard

"react-virtualized-auto-sizer@npm:1.0.7":
version: 1.0.7
resolution: "react-virtualized-auto-sizer@npm:1.0.7"
peerDependencies:
react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc
react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc
checksum: 10/a16d8ac11a0efa20d44f36a5cf3854027895b806363a409f2ddc07ff92bfc92aaf5b8eee21f3e1b153cee2273db5e5383b6334d4b530d934ed08808ecfb45b9f
languageName: node
linkType: hard

"react-virtualized-auto-sizer@npm:^1.0.2":
version: 1.0.24
resolution: "react-virtualized-auto-sizer@npm:1.0.24"
Expand All @@ -19218,6 +19251,19 @@ __metadata:
languageName: node
linkType: hard

"react-window@npm:1.8.7":
version: 1.8.7
resolution: "react-window@npm:1.8.7"
dependencies:
"@babel/runtime": "npm:^7.0.0"
memoize-one: "npm:>=3.1.1 <6"
peerDependencies:
react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
checksum: 10/c838d60be2d2a6535e5a7db63da451aad6bc75f01de37ba3cdab13fee9acc7a75ff16f17772228faadfbfedfa51addc9496806fde92e7bec7bc5f35549b37450
languageName: node
linkType: hard

"react-window@npm:^1.8.5":
version: 1.8.10
resolution: "react-window@npm:1.8.10"
Expand Down

0 comments on commit 17108bc

Please sign in to comment.