@integrigo/integrigo-ui 1.6.17-g → 1.6.17-h
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/jest.config.js +1 -1
- package/lib/index.esm.js +1 -1
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/src/components/atoms/Chip/Chip.stories.d.ts +5 -4
- package/lib/src/components/atoms/Dot/Dot.stories.d.ts +3 -3
- package/lib/src/components/atoms/Icon/Icon.d.ts +1 -0
- package/lib/src/components/atoms/Icon/Icon.stories.d.ts +2 -2
- package/lib/src/components/atoms/Icon/IconAddition.d.ts +5 -5
- package/lib/src/components/atoms/Icon/icons/Eye.d.ts +3 -0
- package/lib/src/components/atoms/Icon/icons/Search.d.ts +3 -0
- package/lib/src/components/molecules/Checkbox/Checkbox.stories.d.ts +4 -4
- package/lib/src/components/molecules/Input/Input.d.ts +8 -8
- package/lib/src/components/molecules/Input/Input.stories.d.ts +9 -9
- package/lib/src/components/molecules/Radio/Radio.stories.d.ts +4 -4
- package/lib/src/components/organisms/Table/Table.d.ts +12 -0
- package/lib/src/components/organisms/Table/Table.stories.d.ts +7 -0
- package/lib/src/components/organisms/Table/Table.test.d.ts +1 -0
- package/lib/src/components/organisms/Table/index.d.ts +1 -0
- package/lib/src/components/organisms/index.d.ts +1 -0
- package/lib/src/index.d.ts +4 -4
- package/package.json +7 -6
- package/src/components/atoms/Chip/Chip.stories.tsx +21 -20
- package/src/components/atoms/Icon/Icon.tsx +2 -0
- package/src/components/atoms/Icon/IconAddition.tsx +22 -20
- package/src/components/atoms/Icon/icons/Eye.tsx +9 -0
- package/src/components/atoms/Icon/icons/Search.tsx +9 -0
- package/src/components/molecules/Button/BasicButton.tsx +2 -1
- package/src/components/molecules/Button/Button.tsx +5 -4
- package/src/components/molecules/Input/Input.tsx +51 -47
- package/src/components/organisms/Table/Table.stories.tsx +180 -0
- package/src/components/organisms/Table/Table.test.tsx +82 -0
- package/src/components/organisms/Table/Table.tsx +162 -0
- package/src/components/organisms/Table/__snapshots__/Table.test.tsx.snap +101 -0
- package/src/components/organisms/Table/index.ts +1 -0
- package/src/components/organisms/index.ts +3 -2
- package/src/index.ts +4 -4
@@ -14,7 +14,7 @@ export const sizeVariants = {
|
|
14
14
|
font: '16px',
|
15
15
|
},
|
16
16
|
m: {
|
17
|
-
iconPadding: '
|
17
|
+
iconPadding: '32px',
|
18
18
|
padding: '10px 16px',
|
19
19
|
ghostPadding: '20px',
|
20
20
|
font: '12px',
|
@@ -65,6 +65,7 @@ export const BasicButton = styled.div<{
|
|
65
65
|
padding: ${(p) => sizeVariants[p.sizeVariant].padding};
|
66
66
|
font-weight: var(--font-bold);
|
67
67
|
font-size: ${(p) => sizeVariants[p.sizeVariant].font};
|
68
|
+
line-height: ${(p) => sizeVariants[p.sizeVariant].font};
|
68
69
|
cursor: pointer;
|
69
70
|
overflow: hidden;
|
70
71
|
position: relative;
|
@@ -72,7 +72,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
72
72
|
{...props}
|
73
73
|
>
|
74
74
|
{direction !== 'rtl' && (
|
75
|
-
<IconOffset size={size} ghost={Boolean(props.ghost)}>
|
75
|
+
// <IconOffset size={size} ghost={Boolean(props.ghost)}>
|
76
76
|
<IconAddition
|
77
77
|
icon={icon}
|
78
78
|
size={size}
|
@@ -81,7 +81,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
81
81
|
direction={direction}
|
82
82
|
onClick={onIconClick}
|
83
83
|
/>
|
84
|
-
</IconOffset>
|
84
|
+
// </IconOffset>
|
85
85
|
)}
|
86
86
|
|
87
87
|
<ButtonComponent
|
@@ -103,7 +103,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
103
103
|
</ButtonComponent>
|
104
104
|
|
105
105
|
{direction === 'rtl' && (
|
106
|
-
<IconOffset size={size} ghost={Boolean(props.ghost)} right>
|
106
|
+
// <IconOffset size={size} ghost={Boolean(props.ghost)} right>
|
107
107
|
<IconAddition
|
108
108
|
icon={icon}
|
109
109
|
size={size}
|
@@ -112,7 +112,7 @@ export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
112
112
|
direction={direction}
|
113
113
|
onClick={onIconClick}
|
114
114
|
/>
|
115
|
-
</IconOffset>
|
115
|
+
// </IconOffset>
|
116
116
|
)}
|
117
117
|
</ButtonWrapper>
|
118
118
|
);
|
@@ -152,6 +152,7 @@ const IconOffset = styled.div<{
|
|
152
152
|
}>`
|
153
153
|
position: absolute;
|
154
154
|
bottom: 0;
|
155
|
+
|
155
156
|
${(p) =>
|
156
157
|
p.right
|
157
158
|
? `right: ${p.ghost ? 0 : sizeVariant[p.size]}`
|
@@ -1,36 +1,36 @@
|
|
1
|
-
import React from
|
2
|
-
import styled, { css, FlattenSimpleInterpolation } from
|
3
|
-
import { FieldProps } from
|
1
|
+
import React from "react";
|
2
|
+
import styled, { css, FlattenSimpleInterpolation } from "styled-components";
|
3
|
+
import { FieldProps } from "formik";
|
4
4
|
|
5
|
-
import { getValidationTypeProps } from
|
6
|
-
import { ValidationType } from
|
7
|
-
import { IconAddition, IconType } from
|
8
|
-
import { Label } from
|
9
|
-
import { FieldLabel, fieldSizeVariants, FieldWrapper } from
|
5
|
+
import { getValidationTypeProps } from "../../../helpers/validation";
|
6
|
+
import { ValidationType } from "../../../types/validation";
|
7
|
+
import { IconAddition, IconType } from "../../atoms/Icon";
|
8
|
+
import { Label } from "../../atoms/Typography/Label";
|
9
|
+
import { FieldLabel, fieldSizeVariants, FieldWrapper } from "../../atoms/Field";
|
10
10
|
|
11
11
|
export type InputProps = Omit<
|
12
|
-
React.InputHTMLAttributes<HTMLInputElement>,
|
13
|
-
|
12
|
+
React.InputHTMLAttributes<HTMLInputElement>,
|
13
|
+
"size"
|
14
14
|
> &
|
15
|
-
FieldProps & {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
};
|
15
|
+
FieldProps & {
|
16
|
+
label?: string;
|
17
|
+
validationType?: ValidationType;
|
18
|
+
icon?: IconType;
|
19
|
+
size?: "xl" | "l" | "m" | "s";
|
20
|
+
direction?: "ltr" | "rtl";
|
21
|
+
onIconClick?: () => void;
|
22
|
+
};
|
23
23
|
|
24
24
|
const getDirectionPadding = (
|
25
|
-
direction: InputProps[
|
26
|
-
padding: string
|
25
|
+
direction: InputProps["direction"],
|
26
|
+
padding: string
|
27
27
|
): FlattenSimpleInterpolation => {
|
28
28
|
switch (direction) {
|
29
|
-
case
|
29
|
+
case "ltr":
|
30
30
|
return css`
|
31
31
|
padding-left: ${padding};
|
32
32
|
`;
|
33
|
-
case
|
33
|
+
case "rtl":
|
34
34
|
return css`
|
35
35
|
padding-right: ${padding};
|
36
36
|
`;
|
@@ -40,7 +40,7 @@ const getDirectionPadding = (
|
|
40
40
|
};
|
41
41
|
|
42
42
|
export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
43
|
-
({ icon, label, size =
|
43
|
+
({ icon, label, size = "m", onIconClick, field, ...props }, ref) => (
|
44
44
|
<FieldWrapper withLabel={Boolean(label)} sizeVariant={size}>
|
45
45
|
{label && (
|
46
46
|
<FieldLabel sizeVariant={size}>
|
@@ -48,34 +48,36 @@ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
|
|
48
48
|
</FieldLabel>
|
49
49
|
)}
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
<InputWrapper>
|
52
|
+
{props.direction !== "rtl" && (
|
53
|
+
<IconAddition
|
54
|
+
icon={icon}
|
55
|
+
disabled={props.disabled}
|
56
|
+
direction={props.direction}
|
57
|
+
onClick={onIconClick}
|
58
|
+
size={size}
|
59
|
+
/>
|
60
|
+
)}
|
60
61
|
|
61
|
-
|
62
|
+
<InputElement ref={ref} sizeVariant={size} {...field} {...props} />
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
{props.direction === "rtl" && (
|
65
|
+
<IconAddition
|
66
|
+
icon={icon}
|
67
|
+
disabled={props.disabled}
|
68
|
+
direction={props.direction}
|
69
|
+
onClick={onIconClick}
|
70
|
+
/>
|
71
|
+
)}
|
72
|
+
</InputWrapper>
|
71
73
|
</FieldWrapper>
|
72
|
-
)
|
74
|
+
)
|
73
75
|
);
|
74
76
|
|
75
77
|
const InputElement = styled.input<
|
76
|
-
Pick<InputProps,
|
77
|
-
|
78
|
-
}
|
78
|
+
Pick<InputProps, "validationType" | "direction"> & {
|
79
|
+
sizeVariant: "xl" | "l" | "m" | "s";
|
80
|
+
}
|
79
81
|
>`
|
80
82
|
background-color: var(--color-white);
|
81
83
|
border: 2px solid var(--shades-of-grey-80);
|
@@ -105,7 +107,7 @@ Pick<InputProps, 'validationType' | 'direction'> & {
|
|
105
107
|
${(p) =>
|
106
108
|
getDirectionPadding(
|
107
109
|
p.direction,
|
108
|
-
fieldSizeVariants[p.sizeVariant].iconPadding
|
110
|
+
fieldSizeVariants[p.sizeVariant].iconPadding
|
109
111
|
)};
|
110
112
|
|
111
113
|
&:disabled {
|
@@ -117,4 +119,6 @@ Pick<InputProps, 'validationType' | 'direction'> & {
|
|
117
119
|
}
|
118
120
|
`;
|
119
121
|
|
120
|
-
|
122
|
+
const InputWrapper = styled.div`
|
123
|
+
position: relative;
|
124
|
+
`;
|
@@ -0,0 +1,180 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { Table } from './Table';
|
3
|
+
import { ComponentMeta, ComponentStory } from '@storybook/react';
|
4
|
+
|
5
|
+
import {
|
6
|
+
Column,
|
7
|
+
createColumnHelper,
|
8
|
+
} from '@tanstack/react-table';
|
9
|
+
import { Button, Profile } from '../../molecules';
|
10
|
+
|
11
|
+
export default {
|
12
|
+
title: 'Organisms/Table',
|
13
|
+
component: Table,
|
14
|
+
argTypes: {
|
15
|
+
variant: {
|
16
|
+
name: 'Color variant',
|
17
|
+
type: {
|
18
|
+
name: 'string',
|
19
|
+
required: false,
|
20
|
+
},
|
21
|
+
control: {
|
22
|
+
type: 'select',
|
23
|
+
},
|
24
|
+
options: ['primary', 'secondary'],
|
25
|
+
defaultValue: 'primary',
|
26
|
+
},
|
27
|
+
textAlign: {
|
28
|
+
name: 'Text alignment',
|
29
|
+
type: {
|
30
|
+
name: 'string',
|
31
|
+
required: false,
|
32
|
+
},
|
33
|
+
control: {
|
34
|
+
type: 'select',
|
35
|
+
},
|
36
|
+
options: ['left', 'right', 'center'],
|
37
|
+
defaultValue: 'center',
|
38
|
+
},
|
39
|
+
},
|
40
|
+
} as ComponentMeta<typeof Table>;
|
41
|
+
|
42
|
+
export const Primary: ComponentStory<typeof Table> = (args) => {
|
43
|
+
type Person = {
|
44
|
+
firstName: string
|
45
|
+
lastName: string
|
46
|
+
age: number
|
47
|
+
visits: number
|
48
|
+
status: string
|
49
|
+
progress: number
|
50
|
+
};
|
51
|
+
|
52
|
+
const personData: Person[] = [
|
53
|
+
{
|
54
|
+
firstName: 'tanner',
|
55
|
+
lastName: 'linsley',
|
56
|
+
age: 24,
|
57
|
+
visits: 100,
|
58
|
+
status: 'In Relationship',
|
59
|
+
progress: 50,
|
60
|
+
},
|
61
|
+
{
|
62
|
+
firstName: 'tandy',
|
63
|
+
lastName: 'miller',
|
64
|
+
age: 40,
|
65
|
+
visits: 40,
|
66
|
+
status: 'Single',
|
67
|
+
progress: 80,
|
68
|
+
},
|
69
|
+
{
|
70
|
+
firstName: 'joe',
|
71
|
+
lastName: 'dirte',
|
72
|
+
age: 45,
|
73
|
+
visits: 20,
|
74
|
+
status: 'Complicated',
|
75
|
+
progress: 10,
|
76
|
+
},
|
77
|
+
];
|
78
|
+
|
79
|
+
const personColumnHelper = createColumnHelper<Person>();
|
80
|
+
|
81
|
+
const personColumns = [
|
82
|
+
personColumnHelper.accessor('firstName', {
|
83
|
+
cell: info => info.getValue(),
|
84
|
+
footer: info => info.column.id,
|
85
|
+
}),
|
86
|
+
personColumnHelper.accessor(row => row.lastName, {
|
87
|
+
id: 'lastName',
|
88
|
+
cell: info => info.getValue(),
|
89
|
+
header: () => 'Last Name',
|
90
|
+
footer: info => info.column.id,
|
91
|
+
}),
|
92
|
+
personColumnHelper.accessor('age', {
|
93
|
+
header: () => 'Age',
|
94
|
+
cell: info => info.renderValue(),
|
95
|
+
footer: info => info.column.id,
|
96
|
+
}),
|
97
|
+
personColumnHelper.accessor('visits', {
|
98
|
+
header: () => 'Visits',
|
99
|
+
footer: info => info.column.id,
|
100
|
+
}),
|
101
|
+
personColumnHelper.accessor('status', {
|
102
|
+
header: 'Status',
|
103
|
+
footer: info => info.column.id,
|
104
|
+
}),
|
105
|
+
personColumnHelper.accessor('progress', {
|
106
|
+
header: 'Profile Progress',
|
107
|
+
footer: info => info.column.id,
|
108
|
+
}),
|
109
|
+
] as Column<Person>[];
|
110
|
+
|
111
|
+
return (
|
112
|
+
<Table columns={personColumns} data={personData} variant={args.variant} textAlign={args.textAlign}/>
|
113
|
+
);
|
114
|
+
};
|
115
|
+
|
116
|
+
export const WithProfile: ComponentStory<typeof Table> = (args) => {
|
117
|
+
type DataType = {
|
118
|
+
fullName: string;
|
119
|
+
points: number;
|
120
|
+
avatar: string;
|
121
|
+
email: string;
|
122
|
+
};
|
123
|
+
|
124
|
+
const data: DataType[] = [
|
125
|
+
{
|
126
|
+
fullName: 'Tanner Linsley',
|
127
|
+
points: 24,
|
128
|
+
avatar: 'https://img.freepik.com/darmowe-zdjecie/dosc-usmiechnieta-radosnie-kobieta-o-jasnych-wlosach-ubrana-swobodnie-wygladajaca-z-zadowoleniem_176420-15187.jpg?w=1380&t=st=1660198496~exp=1660199096~hmac=7401572065d2cd7bb67d9f43dbde5c116b90aad419b179fffac1196df24869f2',
|
129
|
+
email: 'abc@abc.pl',
|
130
|
+
},
|
131
|
+
{
|
132
|
+
fullName: 'Tandy Miller',
|
133
|
+
points: 80,
|
134
|
+
avatar: 'https://img.freepik.com/darmowe-zdjecie/dosc-usmiechnieta-radosnie-kobieta-o-jasnych-wlosach-ubrana-swobodnie-wygladajaca-z-zadowoleniem_176420-15187.jpg?w=1380&t=st=1660198496~exp=1660199096~hmac=7401572065d2cd7bb67d9f43dbde5c116b90aad419b179fffac1196df24869f2',
|
135
|
+
email: 'def@def.pl',
|
136
|
+
},
|
137
|
+
{
|
138
|
+
fullName: 'Joe Dirte',
|
139
|
+
points: 45,
|
140
|
+
avatar: 'https://img.freepik.com/darmowe-zdjecie/dosc-usmiechnieta-radosnie-kobieta-o-jasnych-wlosach-ubrana-swobodnie-wygladajaca-z-zadowoleniem_176420-15187.jpg?w=1380&t=st=1660198496~exp=1660199096~hmac=7401572065d2cd7bb67d9f43dbde5c116b90aad419b179fffac1196df24869f2',
|
141
|
+
email: 'ghi@ghi.pl',
|
142
|
+
},
|
143
|
+
];
|
144
|
+
|
145
|
+
const profileColumnHelper = createColumnHelper<DataType>();
|
146
|
+
|
147
|
+
const columns = [
|
148
|
+
profileColumnHelper.accessor('fullName', {
|
149
|
+
cell: info => {
|
150
|
+
return (
|
151
|
+
<div style={{ display: 'flex', alignItems: 'center' }}>
|
152
|
+
<div style={{ flexBasis: '20px' }}>{info.row.index + 1}.</div>
|
153
|
+
<Profile
|
154
|
+
name={info.getValue()}
|
155
|
+
src={info.row.original.avatar}
|
156
|
+
>
|
157
|
+
<span>{info.row.original.email}</span>
|
158
|
+
</Profile>
|
159
|
+
</div>
|
160
|
+
);
|
161
|
+
},
|
162
|
+
header: () => 'Team member',
|
163
|
+
footer: info => info.column.id,
|
164
|
+
}),
|
165
|
+
profileColumnHelper.accessor('points', {
|
166
|
+
header: () => 'Points',
|
167
|
+
cell: info => info.renderValue(),
|
168
|
+
footer: info => info.column.id,
|
169
|
+
}),
|
170
|
+
profileColumnHelper.display({
|
171
|
+
header: 'Actions',
|
172
|
+
id: 'Actions',
|
173
|
+
cell: () => <div style={{ width: '30px' }}><Button direction={'ltr'} icon={'edit'} ghost>Edit</Button></div>,
|
174
|
+
}),
|
175
|
+
] as Column<DataType>[];
|
176
|
+
|
177
|
+
return (
|
178
|
+
<Table columns={columns} data={data} variant={args.variant} width={'100%'} textAlign={"left"}/>
|
179
|
+
);
|
180
|
+
};
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { render } from '@testing-library/react';
|
3
|
+
import { Table } from './Table';
|
4
|
+
import { Column, createColumnHelper } from '@tanstack/react-table';
|
5
|
+
|
6
|
+
type Person = {
|
7
|
+
firstName: string
|
8
|
+
lastName: string
|
9
|
+
age: number
|
10
|
+
visits: number
|
11
|
+
status: string
|
12
|
+
progress: number
|
13
|
+
};
|
14
|
+
|
15
|
+
const data: Person[] = [
|
16
|
+
{
|
17
|
+
firstName: 'tanner',
|
18
|
+
lastName: 'linsley',
|
19
|
+
age: 24,
|
20
|
+
visits: 100,
|
21
|
+
status: 'In Relationship',
|
22
|
+
progress: 50,
|
23
|
+
},
|
24
|
+
{
|
25
|
+
firstName: 'tandy',
|
26
|
+
lastName: 'miller',
|
27
|
+
age: 40,
|
28
|
+
visits: 40,
|
29
|
+
status: 'Single',
|
30
|
+
progress: 80,
|
31
|
+
},
|
32
|
+
{
|
33
|
+
firstName: 'joe',
|
34
|
+
lastName: 'dirte',
|
35
|
+
age: 45,
|
36
|
+
visits: 20,
|
37
|
+
status: 'Complicated',
|
38
|
+
progress: 10,
|
39
|
+
},
|
40
|
+
];
|
41
|
+
|
42
|
+
const columnHelper = createColumnHelper<Person>();
|
43
|
+
|
44
|
+
const columns = [
|
45
|
+
columnHelper.accessor('firstName', {
|
46
|
+
cell: info => info.getValue(),
|
47
|
+
footer: info => info.column.id,
|
48
|
+
}),
|
49
|
+
columnHelper.accessor(row => row.lastName, {
|
50
|
+
id: 'lastName',
|
51
|
+
cell: info => info.getValue(),
|
52
|
+
header: () => 'Last Name',
|
53
|
+
footer: info => info.column.id,
|
54
|
+
}),
|
55
|
+
columnHelper.accessor('age', {
|
56
|
+
header: () => 'Age',
|
57
|
+
cell: info => info.renderValue(),
|
58
|
+
footer: info => info.column.id,
|
59
|
+
}),
|
60
|
+
columnHelper.accessor('visits', {
|
61
|
+
header: () => 'Visits',
|
62
|
+
footer: info => info.column.id,
|
63
|
+
}),
|
64
|
+
columnHelper.accessor('status', {
|
65
|
+
header: 'Status',
|
66
|
+
footer: info => info.column.id,
|
67
|
+
}),
|
68
|
+
columnHelper.accessor('progress', {
|
69
|
+
header: 'Profile Progress',
|
70
|
+
footer: info => info.column.id,
|
71
|
+
}),
|
72
|
+
] as Column<Person>[];
|
73
|
+
|
74
|
+
describe('<Table />', () => {
|
75
|
+
it('should render', () => {
|
76
|
+
render(<Table columns={columns} data={data}/>);
|
77
|
+
});
|
78
|
+
it('enabled - should match snapshot', () => {
|
79
|
+
const { container } = render(<Table columns={columns} data={data}/>);
|
80
|
+
expect(container).toMatchSnapshot();
|
81
|
+
});
|
82
|
+
});
|
@@ -0,0 +1,162 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import {
|
3
|
+
Column,
|
4
|
+
flexRender,
|
5
|
+
getCoreRowModel,
|
6
|
+
useReactTable,
|
7
|
+
} from '@tanstack/react-table';
|
8
|
+
import styled from 'styled-components';
|
9
|
+
|
10
|
+
type Variant = 'primary' | 'secondary';
|
11
|
+
type Alignment = 'left' | 'right' | 'center';
|
12
|
+
|
13
|
+
const colorVariant = {
|
14
|
+
primary: {
|
15
|
+
backgroundColor: 'var(--color-orange)',
|
16
|
+
fontColor: 'var(--color-white)',
|
17
|
+
},
|
18
|
+
secondary: {
|
19
|
+
backgroundColor: 'var(--color-navy)',
|
20
|
+
fontColor: 'var(--color-white)',
|
21
|
+
},
|
22
|
+
};
|
23
|
+
|
24
|
+
export interface Props <T extends Record<string, unknown>> extends React.TableHTMLAttributes<HTMLTableElement> {
|
25
|
+
data: T[];
|
26
|
+
columns: Column<T>[];
|
27
|
+
variant?: Variant;
|
28
|
+
textAlign?: Alignment
|
29
|
+
}
|
30
|
+
|
31
|
+
export const Table = <T extends Record<string, unknown>>({
|
32
|
+
data,
|
33
|
+
columns,
|
34
|
+
variant = 'primary',
|
35
|
+
textAlign = 'center',
|
36
|
+
...props
|
37
|
+
}: Props<T>) => {
|
38
|
+
|
39
|
+
const table = useReactTable({
|
40
|
+
data,
|
41
|
+
columns,
|
42
|
+
getCoreRowModel: getCoreRowModel(),
|
43
|
+
});
|
44
|
+
|
45
|
+
return (
|
46
|
+
<div>
|
47
|
+
<StyledTable cellSpacing={0} {...props}>
|
48
|
+
<StyledHead variant={variant} textAlign={textAlign}>
|
49
|
+
{table.getHeaderGroups().map(headerGroup => (
|
50
|
+
<tr key={headerGroup.id}>
|
51
|
+
{headerGroup.headers.map(header => (
|
52
|
+
<th key={header.id}>
|
53
|
+
{header.isPlaceholder
|
54
|
+
? null
|
55
|
+
: flexRender(
|
56
|
+
header.column.columnDef.header,
|
57
|
+
header.getContext(),
|
58
|
+
)}
|
59
|
+
</th>
|
60
|
+
))}
|
61
|
+
</tr>
|
62
|
+
))}
|
63
|
+
</StyledHead>
|
64
|
+
<StyledBody textAlign={textAlign}>
|
65
|
+
{table.getRowModel().rows.map(row => (
|
66
|
+
<tr key={row.id}>
|
67
|
+
{row.getVisibleCells().map(cell => (
|
68
|
+
<td key={cell.id}>
|
69
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
70
|
+
</td>
|
71
|
+
))}
|
72
|
+
</tr>
|
73
|
+
))}
|
74
|
+
</StyledBody>
|
75
|
+
</StyledTable>
|
76
|
+
</div>
|
77
|
+
);
|
78
|
+
};
|
79
|
+
|
80
|
+
const StyledTable = styled.table`
|
81
|
+
|
82
|
+
`;
|
83
|
+
|
84
|
+
StyledTable.displayName = 'StyledTable';
|
85
|
+
|
86
|
+
const StyledHead = styled.thead<{ variant: Variant, textAlign: Alignment }>`
|
87
|
+
padding: 15px 10px;
|
88
|
+
height: 54px;
|
89
|
+
|
90
|
+
& tr th {
|
91
|
+
font-weight: 700;
|
92
|
+
font-size: 16px;
|
93
|
+
line-height: 24px;
|
94
|
+
padding: 15px 10px;
|
95
|
+
color: white;
|
96
|
+
text-align: ${props => props.textAlign};
|
97
|
+
}
|
98
|
+
|
99
|
+
${(p) => `
|
100
|
+
background-color: ${colorVariant[p.variant].backgroundColor};
|
101
|
+
color: ${colorVariant[p.variant].fontColor};
|
102
|
+
|
103
|
+
& th:first-child {
|
104
|
+
box-shadow: -10px 0px 10px 1px rgba(0, 0, 0, 0.1);
|
105
|
+
border-radius: 5px 0px 0px 0px;
|
106
|
+
}
|
107
|
+
|
108
|
+
& th:last-child {
|
109
|
+
box-shadow: 10px 0px 10px 1px rgba(0, 0, 0, 0.1);
|
110
|
+
border-radius: 0px 5px 0px 0px;
|
111
|
+
}
|
112
|
+
`}
|
113
|
+
`;
|
114
|
+
|
115
|
+
StyledHead.displayName = 'StyledHead';
|
116
|
+
|
117
|
+
const StyledBody = styled.tbody<{ textAlign: Alignment }>`
|
118
|
+
tr, td {
|
119
|
+
//height for td works like min-height. Table cells will grow when the content does not fit.
|
120
|
+
height: 52px;
|
121
|
+
}
|
122
|
+
|
123
|
+
tr td {
|
124
|
+
padding: 10px;
|
125
|
+
text-align: ${props => props.textAlign};
|
126
|
+
}
|
127
|
+
|
128
|
+
tr:nth-child(even) {
|
129
|
+
background-color: var(--shades-of-grey-0);
|
130
|
+
}
|
131
|
+
|
132
|
+
tr:nth-child(odd) {
|
133
|
+
background-color: var(--shades-of-grey-20);
|
134
|
+
}
|
135
|
+
|
136
|
+
tr:hover {
|
137
|
+
background-color: rgba(224, 154, 51, 0.2);
|
138
|
+
|
139
|
+
td {
|
140
|
+
border-top: solid 2px var(--color-orange);
|
141
|
+
border-bottom: solid 2px var(--color-orange);
|
142
|
+
}
|
143
|
+
|
144
|
+
td:first-child {
|
145
|
+
border-left: solid 2px var(--color-orange);
|
146
|
+
border-bottom: solid 2px var(--color-orange);
|
147
|
+
border-top: solid 2px var(--color-orange);
|
148
|
+
border-top-left-radius: 10px;
|
149
|
+
border-bottom-left-radius: 10px;
|
150
|
+
}
|
151
|
+
|
152
|
+
td:last-child {
|
153
|
+
border-right: solid 2px var(--color-orange);
|
154
|
+
border-bottom: solid 2px var(--color-orange);
|
155
|
+
border-top: solid 2px var(--color-orange);
|
156
|
+
border-top-right-radius: 10px;
|
157
|
+
border-bottom-right-radius: 10px;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
`;
|
161
|
+
|
162
|
+
StyledBody.displayName = 'StyledBody';
|