Skip to content

Commit c3313aa

Browse files
authored
Merge pull request #6 from make-software/feature/BLOX-3235-add-table-component-to-lib
Added table component to lib
2 parents 535c3e2 + e00c338 commit c3313aa

17 files changed

Lines changed: 1172 additions & 0 deletions
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
import { BaseTable, BaseTableProps } from './base-table';
3+
import { Meta, StoryFn } from '@storybook/react';
4+
import TableDataHeader from '../table-data-header/table-data-header';
5+
import TableRow from '../table-row/table-row';
6+
import TableData from '../table-data/table-data';
7+
import BodyText from '../body-text/body-text';
8+
import { PrecisionCase } from '../../utils/currency';
9+
import Cspr from '../cspr/cspr';
10+
import PageTile from '../page-tile/page-tile';
11+
12+
const mockedData = [
13+
{ rank: 1, motes: '50000000000000', owner: 'konrad.cspr' },
14+
{ rank: 2, motes: '482900000000000', owner: 'victoria.cspr' },
15+
{ rank: 3, motes: '1000000', owner: 'ab.cspr' },
16+
];
17+
18+
export default {
19+
component: BaseTable,
20+
title: 'Components/Table/Base Table',
21+
args: {
22+
renderDataHeaders: () => (
23+
<TableRow>
24+
<TableDataHeader>Rank</TableDataHeader>
25+
<TableDataHeader align={'right'}>Balance</TableDataHeader>{' '}
26+
<TableDataHeader>Owner</TableDataHeader>
27+
</TableRow>
28+
),
29+
renderData: () => (
30+
<>
31+
{mockedData.map((data) => (
32+
<TableRow>
33+
<TableData>
34+
<BodyText size={3}>{data.rank}</BodyText>
35+
</TableData>
36+
<TableData align={'right'}>
37+
<BodyText size={3}>
38+
<Cspr
39+
motes={data.motes}
40+
precisionCase={PrecisionCase.deployCost}
41+
/>
42+
</BodyText>
43+
</TableData>
44+
<TableData>
45+
<BodyText size={3}>{data.owner}</BodyText>
46+
</TableData>
47+
</TableRow>
48+
))}
49+
</>
50+
),
51+
},
52+
} as Meta<typeof BaseTable>;
53+
54+
const Template: StoryFn<typeof BaseTable> = (args: BaseTableProps) => {
55+
return (
56+
<PageTile>
57+
<BaseTable
58+
renderDataHeaders={args.renderDataHeaders}
59+
renderData={args.renderData}
60+
renderFooter={args.renderFooter}
61+
/>
62+
</PageTile>
63+
);
64+
};
65+
66+
export const Primary = Template.bind({});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import React, { ReactNode } from 'react';
2+
import styled from 'styled-components';
3+
import TableHead from '../table-head/table-head';
4+
import TableBody from '../table-body/table-body';
5+
import BodyText from '../body-text/body-text';
6+
7+
export interface BaseTableProps {
8+
renderHeader?: () => ReactNode;
9+
renderDataHeaders?: () => ReactNode;
10+
renderData?: () => ReactNode;
11+
renderFooter?: () => ReactNode;
12+
noData?: boolean;
13+
noDataMessage?: string;
14+
paddingBottom?: number;
15+
}
16+
17+
export const TableContainer = styled.div<{ paddingBottom?: number }>(
18+
({ theme, paddingBottom }) => ({
19+
overflowX: 'auto',
20+
...(paddingBottom && { paddingBottom }),
21+
}),
22+
);
23+
24+
const StyledTable = styled.table(({ theme }) => ({
25+
width: '100%',
26+
position: 'relative',
27+
borderCollapse: 'collapse',
28+
}));
29+
30+
const NoDataContainer = styled.div(({ theme }) => ({
31+
position: 'absolute',
32+
top: 0,
33+
width: '100%',
34+
height: '100%',
35+
display: 'flex',
36+
alignItems: 'center',
37+
justifyContent: 'center',
38+
}));
39+
40+
export function BaseTable(props: BaseTableProps) {
41+
const {
42+
renderHeader,
43+
renderDataHeaders,
44+
renderData,
45+
renderFooter,
46+
noData,
47+
noDataMessage,
48+
paddingBottom,
49+
} = props;
50+
51+
return (
52+
<>
53+
{renderHeader && renderHeader()}
54+
<TableContainer paddingBottom={paddingBottom}>
55+
<StyledTable>
56+
{renderDataHeaders && <TableHead>{renderDataHeaders()}</TableHead>}
57+
{renderData && <TableBody>{renderData()}</TableBody>}
58+
</StyledTable>
59+
</TableContainer>
60+
{renderFooter && renderFooter()}
61+
{noDataMessage && noData && (
62+
<NoDataContainer>
63+
<BodyText size={1}>{noDataMessage}</BodyText>
64+
</NoDataContainer>
65+
)}
66+
</>
67+
);
68+
}
69+
70+
export default BaseTable;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import Button, { ButtonProps } from '../button/button';
4+
import CaptionText from '../caption-text/caption-text';
5+
6+
interface PaginationButtonProps extends ButtonProps {
7+
children?: React.ReactNode;
8+
}
9+
10+
const StyledButton = styled(Button)(({ theme }) =>
11+
theme.withMedia({
12+
width: 'auto',
13+
fontWeight: theme.typography.fontWeight.medium,
14+
minHeight: 24,
15+
padding: ['2px 10px'],
16+
}),
17+
);
18+
19+
const StyledArrowsButton = styled(StyledButton)(({ theme }) =>
20+
theme.withMedia({
21+
padding: ['2px 4px'],
22+
}),
23+
);
24+
25+
export const PaginationButton = ({
26+
children,
27+
...restProps
28+
}: PaginationButtonProps) => {
29+
return (
30+
<StyledButton color={'utility'} lineHeight={'xs'} {...restProps}>
31+
<CaptionText size={2}>{children}</CaptionText>
32+
</StyledButton>
33+
);
34+
};
35+
36+
export const PaginationArrowButton = ({
37+
children,
38+
...restProps
39+
}: PaginationButtonProps) => {
40+
return (
41+
<StyledArrowsButton lineHeight={'xs'} {...restProps}>
42+
{children}
43+
</StyledArrowsButton>
44+
);
45+
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import styled from 'styled-components';
2+
3+
export const PaginationContainer = styled.div(({ theme }) =>
4+
theme.withMedia({
5+
border: 'none',
6+
cursor: 'pointer',
7+
color: theme.styleguideColors.contentRed,
8+
background: theme.styleguideColors.fillSecondary,
9+
borderRadius: theme.borderRadius.base,
10+
fontWeight: theme.typography.fontWeight.medium,
11+
minHeight: 24,
12+
display: 'flex',
13+
alignItems: 'center',
14+
justifyContent: 'space-between',
15+
padding: ['2px 8px'],
16+
':hover': {
17+
background: theme.styleguideColors.fillSecondaryRedHover,
18+
color: theme.styleguideColors.fillPrimaryRedHover,
19+
},
20+
':active': {
21+
background: theme.styleguideColors.fillSecondaryRedClick,
22+
color: theme.styleguideColors.fillPrimaryRedClick,
23+
},
24+
}),
25+
);
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import React, { useState } from 'react';
2+
import styled from 'styled-components';
3+
import { PaginationContainer } from './pagination-container';
4+
import { useClickAway } from '../../hooks/use-click-away';
5+
import CaptionText from '../caption-text/caption-text';
6+
import SvgIcon from '../svg-icon/svg-icon';
7+
import ArrowDownIcon from '../../assets/icons/ic-arrow-down.svg';
8+
9+
export const PaginationDropdownContainer = styled.div(({ theme }) =>
10+
theme.withMedia({
11+
position: 'relative',
12+
minWidth: [58],
13+
}),
14+
);
15+
16+
export const PaginationDropdownMenu = styled.ul(({ theme }) =>
17+
theme.withMedia({
18+
width: '100%',
19+
position: 'absolute',
20+
display: 'block',
21+
background: theme.styleguideColors.fillSecondary,
22+
boxShadow: theme.boxShadow.block,
23+
padding: 0,
24+
margin: '4px 0',
25+
borderRadius: theme.borderRadius.base,
26+
zIndex: theme.zIndex.dropdown,
27+
'& > div': {
28+
borderRadius: 0,
29+
},
30+
'& > :first-child': {
31+
borderRadius: theme.borderRadius.base,
32+
borderBottomLeftRadius: 0,
33+
borderBottomRightRadius: 0,
34+
},
35+
'& > :last-child': {
36+
borderRadius: theme.borderRadius.base,
37+
borderTopLeftRadius: 0,
38+
borderTopRightRadius: 0,
39+
},
40+
}),
41+
);
42+
43+
const PaginationDropdownMenuItem = styled.li(({ theme }) => ({
44+
alignItems: 'center',
45+
display: 'flex',
46+
position: 'relative',
47+
'& > input': {
48+
display: 'none',
49+
},
50+
}));
51+
52+
interface PaginationDropdownProps {
53+
value: number;
54+
items: number[];
55+
onChange: (perPage: number) => void;
56+
}
57+
58+
export const PaginationDropdown = ({
59+
value,
60+
items,
61+
onChange,
62+
}: PaginationDropdownProps) => {
63+
const [opened, setOpened] = useState(false);
64+
65+
const { ref } = useClickAway({
66+
callback: () => {
67+
setOpened(false);
68+
},
69+
});
70+
71+
return (
72+
<PaginationDropdownContainer
73+
ref={ref}
74+
onClick={() => {
75+
setOpened(!opened);
76+
}}
77+
>
78+
<PaginationContainer>
79+
<CaptionText size={1}>{value}</CaptionText>
80+
<SvgIcon
81+
src={ArrowDownIcon}
82+
marginLeft
83+
rotate={opened}
84+
role={'img'}
85+
alt={'Arrow down icon'}
86+
/>
87+
</PaginationContainer>
88+
{opened && (
89+
<PaginationDropdownMenu>
90+
{items.map((item) => (
91+
<PaginationContainer
92+
key={item}
93+
onClick={() => {
94+
onChange(item);
95+
}}
96+
>
97+
<PaginationDropdownMenuItem>
98+
<input
99+
type="radio"
100+
name="rows"
101+
id={`${item}-row`}
102+
defaultChecked={item === value}
103+
value={item}
104+
/>
105+
<CaptionText size={2}>{item}</CaptionText>
106+
</PaginationDropdownMenuItem>
107+
</PaginationContainer>
108+
))}
109+
</PaginationDropdownMenu>
110+
)}
111+
</PaginationDropdownContainer>
112+
);
113+
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import CaptionText from '../caption-text/caption-text';
4+
import FlexBox from '../flex-box/flex-box';
5+
6+
interface PaginationInfoTextProps {
7+
children?: React.ReactNode;
8+
}
9+
10+
export const StyledContainer = styled(FlexBox)(({ theme }) =>
11+
theme.withMedia({
12+
textAlign: 'center',
13+
borderRadius: theme.borderRadius.base,
14+
backgroundColor: theme.styleguideColors.fillSecondary,
15+
color: theme.styleguideColors.contentPrimary,
16+
height: 20,
17+
padding: ['4px 8px', '4px 16px'],
18+
width: '100%',
19+
}),
20+
);
21+
22+
export const PaginationInfoText = ({
23+
children,
24+
...props
25+
}: PaginationInfoTextProps) => {
26+
return (
27+
<StyledContainer {...props} align={'center'} justify={'center'}>
28+
<CaptionText size={2} variation={'black'} noWrap>
29+
{children}
30+
</CaptionText>
31+
</StyledContainer>
32+
);
33+
};

0 commit comments

Comments
 (0)