w-design-system 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/icon/chevron-down.svg +3 -0
- package/dist/assets/icon/chevron-left.svg +3 -0
- package/dist/assets/icon/chevron-right.svg +3 -0
- package/dist/assets/icon/dump.svg +3 -0
- package/dist/assets/icon/edit.svg +10 -0
- package/dist/assets/icon/index.d.ts +6 -1
- package/dist/assets/icon/index.d.ts.map +1 -1
- package/dist/assets/icon/index.js +6 -1
- package/dist/assets/icon/index.js.map +1 -1
- package/dist/assets/icon/index.ts +17 -1
- package/dist/assets/icon/spin.svg +3 -0
- package/dist/components/ButtonRound/index.d.ts.map +1 -1
- package/dist/components/ButtonRound/index.js +4 -4
- package/dist/components/ButtonRound/index.js.map +1 -1
- package/dist/components/ButtonRound/stories.d.ts.map +1 -1
- package/dist/components/ButtonRound/stories.js +1 -2
- package/dist/components/ButtonRound/stories.js.map +1 -1
- package/dist/components/ButtonRound/styles.js +5 -5
- package/dist/components/ButtonRound/styles.js.map +1 -1
- package/dist/components/CardStories/index.d.ts +9 -0
- package/dist/components/CardStories/index.d.ts.map +1 -0
- package/dist/components/CardStories/index.js +43 -0
- package/dist/components/CardStories/index.js.map +1 -0
- package/dist/components/CardStories/stories.d.ts +9 -0
- package/dist/components/CardStories/stories.d.ts.map +1 -0
- package/dist/components/CardStories/stories.js +35 -0
- package/dist/components/CardStories/stories.js.map +1 -0
- package/dist/components/Loading/index.d.ts +8 -0
- package/dist/components/Loading/index.d.ts.map +1 -0
- package/dist/components/Loading/index.js +50 -0
- package/dist/components/Loading/index.js.map +1 -0
- package/dist/components/Loading/stories.d.ts +12 -0
- package/dist/components/Loading/stories.d.ts.map +1 -0
- package/dist/components/Loading/stories.js +46 -0
- package/dist/components/Loading/stories.js.map +1 -0
- package/dist/components/Modal/stories.js +1 -1
- package/dist/components/Modal/stories.js.map +1 -1
- package/dist/components/Paginate/index.d.ts +10 -0
- package/dist/components/Paginate/index.d.ts.map +1 -0
- package/dist/components/Paginate/index.js +58 -0
- package/dist/components/Paginate/index.js.map +1 -0
- package/dist/components/Paginate/stories.d.ts +6 -0
- package/dist/components/Paginate/stories.d.ts.map +1 -0
- package/dist/components/Paginate/stories.js +37 -0
- package/dist/components/Paginate/stories.js.map +1 -0
- package/dist/components/Paginate/styles.d.ts +2 -0
- package/dist/components/Paginate/styles.d.ts.map +1 -0
- package/dist/components/Paginate/styles.js +97 -0
- package/dist/components/Paginate/styles.js.map +1 -0
- package/dist/components/Paragraph/index.d.ts +5 -1
- package/dist/components/Paragraph/index.d.ts.map +1 -1
- package/dist/components/Paragraph/index.js +31 -9
- package/dist/components/Paragraph/index.js.map +1 -1
- package/dist/components/Paragraph/stories.d.ts.map +1 -1
- package/dist/components/Paragraph/stories.js +18 -20
- package/dist/components/Paragraph/stories.js.map +1 -1
- package/dist/components/Table/index.d.ts +21 -0
- package/dist/components/Table/index.d.ts.map +1 -0
- package/dist/components/Table/index.js +90 -0
- package/dist/components/Table/index.js.map +1 -0
- package/dist/components/Table/stories.d.ts +9 -0
- package/dist/components/Table/stories.d.ts.map +1 -0
- package/dist/components/Table/stories.js +159 -0
- package/dist/components/Table/stories.js.map +1 -0
- package/dist/components/Table/styles.d.ts +1 -0
- package/dist/components/Table/styles.d.ts.map +1 -0
- package/dist/components/Table/styles.js +2 -0
- package/dist/components/Table/styles.js.map +1 -0
- package/dist/components/Tabs/stories.js +3 -3
- package/dist/components/Tabs/stories.js.map +1 -1
- package/dist/components/Types/index.d.ts +1 -0
- package/dist/components/Types/index.d.ts.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +2 -0
- package/dist/components/index.js.map +1 -1
- package/package.json +1 -1
- package/src/assets/icon/chevron-down.svg +3 -0
- package/src/assets/icon/chevron-left.svg +3 -0
- package/src/assets/icon/chevron-right.svg +3 -0
- package/src/assets/icon/dump.svg +3 -0
- package/src/assets/icon/edit.svg +10 -0
- package/src/assets/icon/index.ts +17 -1
- package/src/assets/icon/spin.svg +3 -0
- package/src/components/ButtonRound/index.tsx +5 -4
- package/src/components/ButtonRound/stories.tsx +2 -2
- package/src/components/ButtonRound/styles.ts +5 -5
- package/src/components/CardStories/index.tsx +59 -0
- package/src/components/CardStories/stories.tsx +44 -0
- package/src/components/Loading/index.tsx +73 -0
- package/src/components/Loading/stories.tsx +65 -0
- package/src/components/Modal/stories.tsx +1 -1
- package/src/components/Paginate/index.tsx +108 -0
- package/src/components/Paginate/stories.tsx +53 -0
- package/src/components/Paginate/styles.ts +96 -0
- package/src/components/Paragraph/index.tsx +30 -11
- package/src/components/Paragraph/stories.tsx +18 -21
- package/src/components/Table/index.tsx +203 -0
- package/src/components/Table/stories.tsx +198 -0
- package/src/components/Table/styles.ts +0 -0
- package/src/components/Tabs/stories.tsx +3 -3
- package/src/components/Types/index.ts +1 -0
- package/src/components/index.tsx +2 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import React, { useState } from 'react'
|
|
3
|
+
|
|
4
|
+
import { action } from '@storybook/addon-actions'
|
|
5
|
+
import { fn } from '@storybook/test'
|
|
6
|
+
import { Paginate, PropsPaginate } from '.'
|
|
7
|
+
|
|
8
|
+
const meta: Meta<PropsPaginate> = {
|
|
9
|
+
title: 'Components/Paginate',
|
|
10
|
+
component: Paginate,
|
|
11
|
+
tags: ['autodocs'],
|
|
12
|
+
args: {
|
|
13
|
+
currentPage: 1,
|
|
14
|
+
itemCount: 100,
|
|
15
|
+
itemsPerPage: 10,
|
|
16
|
+
onChangePage: fn(),
|
|
17
|
+
onChangeItemsPerPage: fn(),
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default meta
|
|
22
|
+
|
|
23
|
+
const NewPaginate = (args: PropsPaginate) => {
|
|
24
|
+
const [currentPage, setCurrentPage] = useState(args.currentPage)
|
|
25
|
+
const [itemCount, setItemCount] = useState(args.itemCount)
|
|
26
|
+
const [itemsPerPage, setItemsPerPage] = useState(args.itemsPerPage)
|
|
27
|
+
|
|
28
|
+
const handleChangePage = (page: number) => {
|
|
29
|
+
setCurrentPage(page)
|
|
30
|
+
action('changePage')(page)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const handleChangeItemsPerPage = (items: number) => {
|
|
34
|
+
setItemsPerPage(items)
|
|
35
|
+
action('changeItemsPerPage')(items)
|
|
36
|
+
}
|
|
37
|
+
return (
|
|
38
|
+
<Paginate
|
|
39
|
+
{...args}
|
|
40
|
+
currentPage={currentPage}
|
|
41
|
+
itemCount={itemCount}
|
|
42
|
+
itemsPerPage={itemsPerPage}
|
|
43
|
+
onChangePage={handleChangePage}
|
|
44
|
+
onChangeItemsPerPage={handleChangeItemsPerPage}
|
|
45
|
+
/>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const Default: StoryObj<PropsPaginate> = {
|
|
50
|
+
render: args => {
|
|
51
|
+
return <NewPaginate {...args} />
|
|
52
|
+
},
|
|
53
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import styled from 'styled-components'
|
|
2
|
+
import { theme } from '../Themes'
|
|
3
|
+
import { chevronDownSVG } from '../../assets/icon'
|
|
4
|
+
export const Container = styled.div`
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: space-between;
|
|
7
|
+
align-items: center;
|
|
8
|
+
|
|
9
|
+
.icon,
|
|
10
|
+
.icon svg,
|
|
11
|
+
.icon svg path {
|
|
12
|
+
fill: ${theme.colors.shade30} !important;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.icon:hover,
|
|
16
|
+
.icon:hover svg,
|
|
17
|
+
.icon:hover svg path {
|
|
18
|
+
fill: ${theme.colors.cyan30} !important;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.icon-disabled,
|
|
22
|
+
.icon-disabled svg,
|
|
23
|
+
.icon-disabled svg path {
|
|
24
|
+
fill: ${theme.colors.shade20} !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
ul.pagination {
|
|
28
|
+
display: flex;
|
|
29
|
+
gap: 1rem;
|
|
30
|
+
font-family: 'Nunito Sans', sans-serif;
|
|
31
|
+
font-size: 1rem;
|
|
32
|
+
color: ${theme.colors.shade40};
|
|
33
|
+
li {
|
|
34
|
+
list-style: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
li.page {
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
li.page:hover {
|
|
42
|
+
color: ${theme.colors.cyan30};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
li.page-active {
|
|
46
|
+
color: ${theme.colors.cyan30};
|
|
47
|
+
cursor: default;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.items-per-page-wrapper {
|
|
52
|
+
display: flex;
|
|
53
|
+
align-items: center;
|
|
54
|
+
|
|
55
|
+
gap: 1rem;
|
|
56
|
+
font-family: 'Nunito Sans', sans-serif;
|
|
57
|
+
color: ${theme.colors.shade40};
|
|
58
|
+
|
|
59
|
+
select {
|
|
60
|
+
/* styling */
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
background-color: ${theme.colors.shade05};
|
|
63
|
+
background-image: url(${chevronDownSVG});
|
|
64
|
+
background-repeat: no-repeat;
|
|
65
|
+
background-size: 1rem;
|
|
66
|
+
background-position: right 1rem top calc(50% + 1px);
|
|
67
|
+
border: 1px solid ${theme.colors.shade20};
|
|
68
|
+
color: ${theme.colors.shade40};
|
|
69
|
+
border-radius: 4px;
|
|
70
|
+
display: inline-block;
|
|
71
|
+
font: inherit;
|
|
72
|
+
outline: 0;
|
|
73
|
+
|
|
74
|
+
padding: 18px 48px 14px 16px;
|
|
75
|
+
|
|
76
|
+
margin: 0;
|
|
77
|
+
-webkit-box-sizing: border-box;
|
|
78
|
+
-moz-box-sizing: border-box;
|
|
79
|
+
box-sizing: border-box;
|
|
80
|
+
-webkit-appearance: none;
|
|
81
|
+
-moz-appearance: none; /* Firefox */
|
|
82
|
+
-webkit-appearance: none; /* Safari and Chrome */
|
|
83
|
+
appearance: none;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
select:hover {
|
|
87
|
+
background-color: ${theme.colors.shade10};
|
|
88
|
+
border: 1px solid ${theme.colors.shade20};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
select:focus {
|
|
92
|
+
background-color: ${theme.colors.shade10};
|
|
93
|
+
border: 1px solid ${theme.colors.shade30};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
`
|
|
@@ -3,10 +3,14 @@ import styled from 'styled-components'
|
|
|
3
3
|
|
|
4
4
|
interface ParagraphProps {
|
|
5
5
|
size?: 'x-small' | 'small' | 'medium' | 'large'
|
|
6
|
-
weight?: 400 | 600 | 700 | 800
|
|
7
6
|
as?: 'span' | 'div' | 'label' | 'p'
|
|
8
|
-
color?: string
|
|
7
|
+
color?: string
|
|
8
|
+
textTransform?: 'none' | 'capitalize' | 'uppercase' | 'lowercase'
|
|
9
9
|
children: React.ReactNode
|
|
10
|
+
lightBod?: boolean
|
|
11
|
+
semiBod?: boolean
|
|
12
|
+
strongBod?: boolean
|
|
13
|
+
heavyBod?: boolean
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
const sizes = {
|
|
@@ -17,25 +21,40 @@ const sizes = {
|
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
const weights = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
lightBod: 400,
|
|
25
|
+
semiBod: 600,
|
|
26
|
+
strongBod: 700,
|
|
27
|
+
heavyBod: 800,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const getFontWeight = (props: ParagraphProps) => {
|
|
31
|
+
if (props.heavyBod) return weights.heavyBod
|
|
32
|
+
if (props.strongBod) return weights.strongBod
|
|
33
|
+
if (props.semiBod) return weights.semiBod
|
|
34
|
+
return weights.lightBod
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
const ParagraphStyled = styled.p<ParagraphProps>`
|
|
27
38
|
margin: 0;
|
|
28
39
|
padding: 0;
|
|
29
|
-
font-size: ${
|
|
30
|
-
font-weight: ${props => (props
|
|
40
|
+
font-size: ${({ size = 'small' }) => sizes[size]};
|
|
41
|
+
font-weight: ${props => getFontWeight(props)};
|
|
31
42
|
line-height: 140%;
|
|
32
43
|
font-family: 'Nunito Sans', sans-serif;
|
|
33
|
-
color: ${
|
|
44
|
+
color: ${({ color = 'inherit' }) => color};
|
|
45
|
+
text-transform: ${({ textTransform = 'none' }) => textTransform};
|
|
34
46
|
`
|
|
35
47
|
|
|
36
|
-
export const Paragraph: React.FC<ParagraphProps> = ({
|
|
48
|
+
export const Paragraph: React.FC<ParagraphProps> = ({
|
|
49
|
+
size = 'small',
|
|
50
|
+
as = 'p',
|
|
51
|
+
color = 'inherit',
|
|
52
|
+
textTransform = 'none',
|
|
53
|
+
children,
|
|
54
|
+
...props
|
|
55
|
+
}) => {
|
|
37
56
|
return (
|
|
38
|
-
<ParagraphStyled as={as} size={size}
|
|
57
|
+
<ParagraphStyled as={as} size={size} color={color} textTransform={textTransform} {...props}>
|
|
39
58
|
{children}
|
|
40
59
|
</ParagraphStyled>
|
|
41
60
|
)
|
|
@@ -13,61 +13,58 @@ const meta: Meta<typeof Paragraph> = {
|
|
|
13
13
|
control: { type: 'select', options: ['x-small', 'small', 'medium', 'large'] },
|
|
14
14
|
description: 'Select the size of the paragraph',
|
|
15
15
|
},
|
|
16
|
-
weight: {
|
|
17
|
-
control: { type: 'select', options: [400, 600, 700, 800] },
|
|
18
|
-
description: 'Select the font weight of the paragraph',
|
|
19
|
-
},
|
|
20
16
|
as: {
|
|
21
17
|
control: { type: 'select', options: ['span', 'div', 'label', 'p'] },
|
|
22
18
|
description: 'Select the HTML element to render',
|
|
23
19
|
},
|
|
24
20
|
color: {
|
|
25
|
-
control: 'color',
|
|
21
|
+
control: 'color',
|
|
26
22
|
description: 'Select the color of the text',
|
|
27
23
|
},
|
|
28
24
|
children: {
|
|
29
25
|
control: 'text',
|
|
30
26
|
description: 'Content of the paragraph',
|
|
31
27
|
},
|
|
28
|
+
semiBod: { control: 'boolean', description: 'Use semiBod weight' },
|
|
29
|
+
strongBod: { control: 'boolean', description: 'Use strongBod weight' },
|
|
30
|
+
heavyBod: { control: 'boolean', description: 'Use heavyBod weight' },
|
|
32
31
|
},
|
|
33
32
|
} satisfies Meta<typeof Paragraph>
|
|
34
33
|
|
|
35
34
|
export default meta
|
|
36
35
|
type Story = StoryObj<typeof meta>
|
|
37
36
|
|
|
38
|
-
// Define different stories for the Paragraph component
|
|
39
|
-
|
|
40
37
|
export const XSmall: Story = {
|
|
41
38
|
args: {
|
|
42
39
|
size: 'x-small',
|
|
43
|
-
color: '#000000',
|
|
44
|
-
children: 'This is an X-small paragraph.',
|
|
40
|
+
color: '#000000',
|
|
41
|
+
children: 'This is an X-small paragraph with LightBod weight.',
|
|
45
42
|
},
|
|
46
43
|
}
|
|
47
44
|
|
|
48
45
|
export const Small: Story = {
|
|
49
46
|
args: {
|
|
50
47
|
size: 'small',
|
|
51
|
-
|
|
52
|
-
color: '#333333',
|
|
53
|
-
children: 'This is a small paragraph with weight
|
|
48
|
+
semiBod: true,
|
|
49
|
+
color: '#333333',
|
|
50
|
+
children: 'This is a small paragraph with SemiBod weight.',
|
|
54
51
|
},
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
export const Medium: Story = {
|
|
58
55
|
args: {
|
|
59
56
|
size: 'medium',
|
|
60
|
-
|
|
61
|
-
color: '#666666',
|
|
62
|
-
children: 'This is a medium paragraph with weight
|
|
57
|
+
strongBod: true,
|
|
58
|
+
color: '#666666',
|
|
59
|
+
children: 'This is a medium paragraph with StrongBod weight.',
|
|
63
60
|
},
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
export const Large: Story = {
|
|
67
64
|
args: {
|
|
68
65
|
size: 'large',
|
|
69
|
-
color: '#999999',
|
|
70
|
-
children: 'This is a large paragraph.',
|
|
66
|
+
color: '#999999',
|
|
67
|
+
children: 'This is a large paragraph with LightBod weight.',
|
|
71
68
|
},
|
|
72
69
|
}
|
|
73
70
|
|
|
@@ -75,8 +72,9 @@ export const CustomElement: Story = {
|
|
|
75
72
|
args: {
|
|
76
73
|
size: 'medium',
|
|
77
74
|
as: 'label',
|
|
78
|
-
color: '#CC0000',
|
|
79
|
-
children: 'This is a medium paragraph rendered as a label.',
|
|
75
|
+
color: '#CC0000',
|
|
76
|
+
children: 'This is a medium paragraph rendered as a label with LightBod weight.',
|
|
77
|
+
strongBod: true,
|
|
80
78
|
},
|
|
81
79
|
}
|
|
82
80
|
|
|
@@ -91,9 +89,8 @@ export const AllSizes: Story = {
|
|
|
91
89
|
export const AllWeights: Story = {
|
|
92
90
|
args: {
|
|
93
91
|
size: 'medium',
|
|
94
|
-
weight: 400,
|
|
95
92
|
color: '#000000',
|
|
96
|
-
children: 'This paragraph weight can be adjusted to
|
|
93
|
+
children: 'This paragraph weight can be adjusted to LightBod, SemiBod, StrongBod, or HeavyBod.',
|
|
97
94
|
},
|
|
98
95
|
}
|
|
99
96
|
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import React, { useState } from 'react'
|
|
2
|
+
import styled from 'styled-components'
|
|
3
|
+
import { Paragraph } from '../Paragraph'
|
|
4
|
+
import { theme } from '../Themes'
|
|
5
|
+
import { ContainerLoading } from '../Loading'
|
|
6
|
+
|
|
7
|
+
type Column = {
|
|
8
|
+
header: string
|
|
9
|
+
accessor: string
|
|
10
|
+
width?: string
|
|
11
|
+
sortable?: boolean
|
|
12
|
+
onClick?: (row: any) => void
|
|
13
|
+
Cell?: (row: any, handleExpandClick: (id: number) => void) => React.ReactNode
|
|
14
|
+
align?: 'left' | 'center' | 'right'
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
type TableProps = {
|
|
18
|
+
columns: Column[] | any
|
|
19
|
+
data: any[]
|
|
20
|
+
height?: string
|
|
21
|
+
loading?: boolean
|
|
22
|
+
emptyStateMessage?: string
|
|
23
|
+
striped?: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const TableContainer = styled.div`
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
width: 100%;
|
|
30
|
+
height: 100%;
|
|
31
|
+
overflow-x: auto;
|
|
32
|
+
`
|
|
33
|
+
|
|
34
|
+
const StyledTable = styled.table`
|
|
35
|
+
width: 100%;
|
|
36
|
+
border-collapse: collapse;
|
|
37
|
+
height: 100%;
|
|
38
|
+
`
|
|
39
|
+
|
|
40
|
+
const Thead = styled.thead`
|
|
41
|
+
display: table-header-group;
|
|
42
|
+
border-bottom: 1px solid #ddd;
|
|
43
|
+
`
|
|
44
|
+
|
|
45
|
+
const Tbody = styled.tbody<{ height?: string }>`
|
|
46
|
+
display: block;
|
|
47
|
+
width: 100%;
|
|
48
|
+
overflow-y: auto;
|
|
49
|
+
height: ${props => props.height || '100%'};
|
|
50
|
+
`
|
|
51
|
+
|
|
52
|
+
const Tr = styled.tr<{ striped?: boolean }>`
|
|
53
|
+
display: table;
|
|
54
|
+
width: 100%;
|
|
55
|
+
table-layout: fixed;
|
|
56
|
+
`
|
|
57
|
+
const TrRow = styled.tr<{ striped?: boolean }>`
|
|
58
|
+
display: table;
|
|
59
|
+
width: 100%;
|
|
60
|
+
table-layout: fixed;
|
|
61
|
+
&:nth-of-type(n + 2) {
|
|
62
|
+
background-color: ${props => (props.striped ? '#f9f9f9' : 'transparent')};
|
|
63
|
+
}
|
|
64
|
+
&:nth-of-type(odd) {
|
|
65
|
+
background-color: ${props => (props.striped ? '#fff' : 'transparent')};
|
|
66
|
+
}
|
|
67
|
+
`
|
|
68
|
+
|
|
69
|
+
const Th = styled.th<{ width?: string; align?: 'left' | 'center' | 'right' }>`
|
|
70
|
+
padding: 10px;
|
|
71
|
+
text-align: ${props => props.align || 'left'};
|
|
72
|
+
width: ${props => props.width || 'auto'};
|
|
73
|
+
`
|
|
74
|
+
|
|
75
|
+
const Td = styled.td<{ width?: string; align: 'left' | 'center' | 'right' }>`
|
|
76
|
+
padding: 12px;
|
|
77
|
+
width: ${props => props?.width || 'auto'};
|
|
78
|
+
text-align: ${props => props?.align || 'left'};
|
|
79
|
+
`
|
|
80
|
+
|
|
81
|
+
const ExpandableRow = styled.div`
|
|
82
|
+
padding: 8px;
|
|
83
|
+
min-height: 50px;
|
|
84
|
+
`
|
|
85
|
+
|
|
86
|
+
const LoadingWrapper = styled.div`
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
justify-content: center;
|
|
90
|
+
width: 100%;
|
|
91
|
+
height: 100%;
|
|
92
|
+
`
|
|
93
|
+
|
|
94
|
+
const EmptyStateWrapper = styled.div`
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
justify-content: center;
|
|
98
|
+
width: 100%;
|
|
99
|
+
height: 100%;
|
|
100
|
+
padding: 20px;
|
|
101
|
+
`
|
|
102
|
+
|
|
103
|
+
export const Table: React.FC<TableProps> = ({
|
|
104
|
+
columns,
|
|
105
|
+
data,
|
|
106
|
+
height = '100%',
|
|
107
|
+
loading = false,
|
|
108
|
+
emptyStateMessage = 'No data available',
|
|
109
|
+
striped = false,
|
|
110
|
+
}) => {
|
|
111
|
+
const [expandedRow, setExpandedRow] = useState<number | null>(null)
|
|
112
|
+
|
|
113
|
+
const handleExpandClick = (id: number) => {
|
|
114
|
+
setExpandedRow(expandedRow === id ? null : id)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// @ts-ignore
|
|
118
|
+
return (
|
|
119
|
+
<TableContainer>
|
|
120
|
+
<StyledTable>
|
|
121
|
+
<Thead>
|
|
122
|
+
<Tr striped={striped}>
|
|
123
|
+
{columns.map(
|
|
124
|
+
(
|
|
125
|
+
col: {
|
|
126
|
+
width: string | undefined
|
|
127
|
+
align: any
|
|
128
|
+
header:
|
|
129
|
+
| string
|
|
130
|
+
| number
|
|
131
|
+
| boolean
|
|
132
|
+
| React.ReactElement<any, string | React.JSXElementConstructor<any>>
|
|
133
|
+
| Iterable<React.ReactNode>
|
|
134
|
+
| React.ReactPortal
|
|
135
|
+
| null
|
|
136
|
+
| undefined
|
|
137
|
+
},
|
|
138
|
+
index: React.Key | null | undefined,
|
|
139
|
+
) => (
|
|
140
|
+
<Th key={index} width={col.width} align={col.align}>
|
|
141
|
+
<Paragraph color={theme.colors.shade30} textTransform={'uppercase'}>
|
|
142
|
+
{col.header}
|
|
143
|
+
</Paragraph>
|
|
144
|
+
</Th>
|
|
145
|
+
),
|
|
146
|
+
)}
|
|
147
|
+
</Tr>
|
|
148
|
+
</Thead>
|
|
149
|
+
<Tbody height={height}>
|
|
150
|
+
{loading ? (
|
|
151
|
+
<LoadingWrapper>
|
|
152
|
+
<ContainerLoading size={'small'} />
|
|
153
|
+
</LoadingWrapper>
|
|
154
|
+
) : data.length === 0 ? (
|
|
155
|
+
<EmptyStateWrapper>
|
|
156
|
+
<Paragraph>{emptyStateMessage}</Paragraph>
|
|
157
|
+
</EmptyStateWrapper>
|
|
158
|
+
) : (
|
|
159
|
+
data.map((row, rowIndex) => (
|
|
160
|
+
<React.Fragment key={row.id}>
|
|
161
|
+
<TrRow striped={striped}>
|
|
162
|
+
{columns.map(
|
|
163
|
+
(
|
|
164
|
+
col: {
|
|
165
|
+
width: string | undefined
|
|
166
|
+
align: any
|
|
167
|
+
Cell: (
|
|
168
|
+
arg0: any,
|
|
169
|
+
arg1: (id: number) => void,
|
|
170
|
+
) =>
|
|
171
|
+
| string
|
|
172
|
+
| number
|
|
173
|
+
| boolean
|
|
174
|
+
| React.ReactElement<any, string | React.JSXElementConstructor<any>>
|
|
175
|
+
| Iterable<React.ReactNode>
|
|
176
|
+
| React.ReactPortal
|
|
177
|
+
| null
|
|
178
|
+
| undefined
|
|
179
|
+
accessor: string | number
|
|
180
|
+
},
|
|
181
|
+
colIndex: React.Key | null | undefined,
|
|
182
|
+
) => (
|
|
183
|
+
<Td key={colIndex} width={col?.width} align={col?.align}>
|
|
184
|
+
{col.Cell ? (
|
|
185
|
+
col.Cell(row, handleExpandClick)
|
|
186
|
+
) : (
|
|
187
|
+
<Paragraph color={theme.colors.shade40}>{row[col.accessor]}</Paragraph>
|
|
188
|
+
)}
|
|
189
|
+
</Td>
|
|
190
|
+
),
|
|
191
|
+
)}
|
|
192
|
+
</TrRow>
|
|
193
|
+
{expandedRow === row.id && row.containerColapsed && (
|
|
194
|
+
<ExpandableRow>{row.containerColapsed(row)}</ExpandableRow>
|
|
195
|
+
)}
|
|
196
|
+
</React.Fragment>
|
|
197
|
+
))
|
|
198
|
+
)}
|
|
199
|
+
</Tbody>
|
|
200
|
+
</StyledTable>
|
|
201
|
+
</TableContainer>
|
|
202
|
+
)
|
|
203
|
+
}
|