@rovula/ui 0.0.10 → 0.0.12
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/cjs/bundle.css +66 -2
- package/dist/cjs/bundle.js +23 -1
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/Button/Button.d.ts +14 -3
- package/dist/cjs/types/components/Button/Buttons.stories.d.ts +8 -6
- package/dist/cjs/types/components/DataTable/DataTable.d.ts +9 -0
- package/dist/cjs/types/components/DataTable/DataTable.stories.d.ts +22 -0
- package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +29 -3
- package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +31 -30
- package/dist/cjs/types/components/Label/Label.stories.d.ts +1 -1
- package/dist/cjs/types/components/RadioGroup/RadioGroup.stories.d.ts +1 -1
- package/dist/cjs/types/components/Table/Table.d.ts +3 -1
- package/dist/cjs/types/components/Table/Table.stories.d.ts +4 -1
- package/dist/cjs/types/components/Text/Text.d.ts +3 -3
- package/dist/cjs/types/components/Text/Text.stories.d.ts +3 -9
- package/dist/cjs/types/components/TextInput/TextInput.d.ts +20 -2
- package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +28 -1
- package/dist/cjs/types/index.d.ts +4 -0
- package/dist/components/Button/Button.js +4 -3
- package/dist/components/DataTable/DataTable.js +71 -0
- package/dist/components/DataTable/DataTable.stories.js +57 -0
- package/dist/components/Dropdown/Dropdown.js +15 -5
- package/dist/components/Dropdown/Dropdown.stories.js +48 -0
- package/dist/components/Table/Table.js +6 -6
- package/dist/components/Text/Text.js +3 -2
- package/dist/components/TextInput/TextInput.js +5 -7
- package/dist/components/TextInput/TextInput.stories.js +22 -0
- package/dist/esm/bundle.css +66 -2
- package/dist/esm/bundle.js +23 -1
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Button/Button.d.ts +14 -3
- package/dist/esm/types/components/Button/Buttons.stories.d.ts +8 -6
- package/dist/esm/types/components/DataTable/DataTable.d.ts +9 -0
- package/dist/esm/types/components/DataTable/DataTable.stories.d.ts +22 -0
- package/dist/esm/types/components/Dropdown/Dropdown.d.ts +29 -3
- package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +31 -30
- package/dist/esm/types/components/Label/Label.stories.d.ts +1 -1
- package/dist/esm/types/components/RadioGroup/RadioGroup.stories.d.ts +1 -1
- package/dist/esm/types/components/Table/Table.d.ts +3 -1
- package/dist/esm/types/components/Table/Table.stories.d.ts +4 -1
- package/dist/esm/types/components/Text/Text.d.ts +3 -3
- package/dist/esm/types/components/Text/Text.stories.d.ts +3 -9
- package/dist/esm/types/components/TextInput/TextInput.d.ts +20 -2
- package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +28 -1
- package/dist/esm/types/index.d.ts +4 -0
- package/dist/index.d.ts +74 -8
- package/dist/index.js +1 -0
- package/dist/src/theme/global.css +85 -2
- package/package.json +3 -1
- package/src/components/Button/Button.tsx +47 -39
- package/src/components/DataTable/DataTable.stories.tsx +72 -0
- package/src/components/DataTable/DataTable.tsx +171 -0
- package/src/components/Dropdown/Dropdown.stories.tsx +87 -3
- package/src/components/Dropdown/Dropdown.tsx +147 -109
- package/src/components/Table/Table.tsx +17 -8
- package/src/components/Text/Text.tsx +21 -19
- package/src/components/TextInput/TextInput.stories.tsx +46 -1
- package/src/components/TextInput/TextInput.tsx +7 -7
- package/src/index.ts +6 -0
|
@@ -860,6 +860,10 @@ body {
|
|
|
860
860
|
position: relative;
|
|
861
861
|
}
|
|
862
862
|
|
|
863
|
+
.sticky {
|
|
864
|
+
position: sticky;
|
|
865
|
+
}
|
|
866
|
+
|
|
863
867
|
.inset-0 {
|
|
864
868
|
inset: 0px;
|
|
865
869
|
}
|
|
@@ -897,6 +901,10 @@ body {
|
|
|
897
901
|
right: 1rem;
|
|
898
902
|
}
|
|
899
903
|
|
|
904
|
+
.top-0 {
|
|
905
|
+
top: 0px;
|
|
906
|
+
}
|
|
907
|
+
|
|
900
908
|
.top-4 {
|
|
901
909
|
top: 1rem;
|
|
902
910
|
}
|
|
@@ -927,6 +935,10 @@ body {
|
|
|
927
935
|
margin-bottom: auto;
|
|
928
936
|
}
|
|
929
937
|
|
|
938
|
+
.ml-3 {
|
|
939
|
+
margin-left: 0.75rem;
|
|
940
|
+
}
|
|
941
|
+
|
|
930
942
|
.mr-2 {
|
|
931
943
|
margin-right: 0.5rem;
|
|
932
944
|
}
|
|
@@ -1038,6 +1050,10 @@ body {
|
|
|
1038
1050
|
height: 54px;
|
|
1039
1051
|
}
|
|
1040
1052
|
|
|
1053
|
+
.h-full {
|
|
1054
|
+
height: 100%;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1041
1057
|
.max-h-60 {
|
|
1042
1058
|
max-height: 15rem;
|
|
1043
1059
|
}
|
|
@@ -1046,6 +1062,10 @@ body {
|
|
|
1046
1062
|
width: 1rem;
|
|
1047
1063
|
}
|
|
1048
1064
|
|
|
1065
|
+
.w-8 {
|
|
1066
|
+
width: 2rem;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1049
1069
|
.w-\[100px\] {
|
|
1050
1070
|
width: 100px;
|
|
1051
1071
|
}
|
|
@@ -1074,6 +1094,10 @@ body {
|
|
|
1074
1094
|
max-width: 32rem;
|
|
1075
1095
|
}
|
|
1076
1096
|
|
|
1097
|
+
.flex-1 {
|
|
1098
|
+
flex: 1 1 0%;
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1077
1101
|
.shrink-0 {
|
|
1078
1102
|
flex-shrink: 0;
|
|
1079
1103
|
}
|
|
@@ -1082,6 +1106,10 @@ body {
|
|
|
1082
1106
|
caption-side: bottom;
|
|
1083
1107
|
}
|
|
1084
1108
|
|
|
1109
|
+
.border-collapse {
|
|
1110
|
+
border-collapse: collapse;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1085
1113
|
.translate-x-\[-50\%\] {
|
|
1086
1114
|
--tw-translate-x: -50%;
|
|
1087
1115
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
@@ -1141,6 +1169,10 @@ body {
|
|
|
1141
1169
|
justify-content: center;
|
|
1142
1170
|
}
|
|
1143
1171
|
|
|
1172
|
+
.justify-between {
|
|
1173
|
+
justify-content: space-between;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1144
1176
|
.gap-1 {
|
|
1145
1177
|
gap: 0.25rem;
|
|
1146
1178
|
}
|
|
@@ -1196,10 +1228,18 @@ body {
|
|
|
1196
1228
|
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
|
|
1197
1229
|
}
|
|
1198
1230
|
|
|
1231
|
+
.self-stretch {
|
|
1232
|
+
align-self: stretch;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1199
1235
|
.overflow-auto {
|
|
1200
1236
|
overflow: auto;
|
|
1201
1237
|
}
|
|
1202
1238
|
|
|
1239
|
+
.overflow-hidden {
|
|
1240
|
+
overflow: hidden;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1203
1243
|
.overflow-x-auto {
|
|
1204
1244
|
overflow-x: auto;
|
|
1205
1245
|
}
|
|
@@ -1208,6 +1248,10 @@ body {
|
|
|
1208
1248
|
overflow-y: auto;
|
|
1209
1249
|
}
|
|
1210
1250
|
|
|
1251
|
+
.overflow-y-scroll {
|
|
1252
|
+
overflow-y: scroll;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1211
1255
|
.whitespace-nowrap {
|
|
1212
1256
|
white-space: nowrap;
|
|
1213
1257
|
}
|
|
@@ -1398,6 +1442,11 @@ body {
|
|
|
1398
1442
|
background-color: rgb(var(--secondary-110) / var(--tw-bg-opacity));
|
|
1399
1443
|
}
|
|
1400
1444
|
|
|
1445
|
+
.bg-secondary-80 {
|
|
1446
|
+
--tw-bg-opacity: 1;
|
|
1447
|
+
background-color: rgb(var(--secondary-80) / var(--tw-bg-opacity));
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1401
1450
|
.bg-success {
|
|
1402
1451
|
--tw-bg-opacity: 1;
|
|
1403
1452
|
background-color: rgb(var(--success-default) / var(--tw-bg-opacity));
|
|
@@ -1514,6 +1563,11 @@ body {
|
|
|
1514
1563
|
padding-bottom: 0.5rem;
|
|
1515
1564
|
}
|
|
1516
1565
|
|
|
1566
|
+
.py-3 {
|
|
1567
|
+
padding-top: 0.75rem;
|
|
1568
|
+
padding-bottom: 0.75rem;
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1517
1571
|
.py-4 {
|
|
1518
1572
|
padding-top: 1rem;
|
|
1519
1573
|
padding-bottom: 1rem;
|
|
@@ -1770,6 +1824,11 @@ body {
|
|
|
1770
1824
|
color: rgb(var(--secondary-110) / var(--tw-text-opacity));
|
|
1771
1825
|
}
|
|
1772
1826
|
|
|
1827
|
+
.text-secondary-120 {
|
|
1828
|
+
--tw-text-opacity: 1;
|
|
1829
|
+
color: rgb(var(--secondary-120) / var(--tw-text-opacity));
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1773
1832
|
.text-secondary-130 {
|
|
1774
1833
|
--tw-text-opacity: 1;
|
|
1775
1834
|
color: rgb(var(--secondary-130) / var(--tw-text-opacity));
|
|
@@ -1815,6 +1874,11 @@ body {
|
|
|
1815
1874
|
color: rgb(var(--text-grey-light) / var(--tw-text-opacity));
|
|
1816
1875
|
}
|
|
1817
1876
|
|
|
1877
|
+
.text-textcolor-grey-medium {
|
|
1878
|
+
--tw-text-opacity: 1;
|
|
1879
|
+
color: rgb(var(--text-grey-medium) / var(--tw-text-opacity));
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1818
1882
|
.text-warning {
|
|
1819
1883
|
--tw-text-opacity: 1;
|
|
1820
1884
|
color: rgb(var(--warning-default) / var(--tw-text-opacity));
|
|
@@ -1902,6 +1966,11 @@ body {
|
|
|
1902
1966
|
--tw-ring-offset-color: hsl(var(--background));
|
|
1903
1967
|
}
|
|
1904
1968
|
|
|
1969
|
+
.blur {
|
|
1970
|
+
--tw-blur: blur(8px);
|
|
1971
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
1972
|
+
}
|
|
1973
|
+
|
|
1905
1974
|
.filter {
|
|
1906
1975
|
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
1907
1976
|
}
|
|
@@ -2364,6 +2433,11 @@ body {
|
|
|
2364
2433
|
background-color: rgb(var(--input-label-background-color) / var(--tw-bg-opacity));
|
|
2365
2434
|
}
|
|
2366
2435
|
|
|
2436
|
+
.peer:focus ~ .peer-focus\:bg-red-500 {
|
|
2437
|
+
--tw-bg-opacity: 1;
|
|
2438
|
+
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2367
2441
|
.peer:focus ~ .peer-focus\:text-input-text-active {
|
|
2368
2442
|
--tw-text-opacity: 1;
|
|
2369
2443
|
color: rgb(var(--input-active-text-color) / var(--tw-text-opacity));
|
|
@@ -2411,6 +2485,11 @@ body {
|
|
|
2411
2485
|
background-color: rgb(var(--primary-default) / var(--tw-bg-opacity));
|
|
2412
2486
|
}
|
|
2413
2487
|
|
|
2488
|
+
.data-\[state\=selected\]\:bg-grey-20[data-state=selected] {
|
|
2489
|
+
--tw-bg-opacity: 1;
|
|
2490
|
+
background-color: rgb(var(--grey-20) / var(--tw-bg-opacity));
|
|
2491
|
+
}
|
|
2492
|
+
|
|
2414
2493
|
.data-\[state\=checked\]\:text-primary-foreground[data-state=checked] {
|
|
2415
2494
|
--tw-text-opacity: 1;
|
|
2416
2495
|
color: rgb(var(--primary-foreground) / var(--tw-text-opacity));
|
|
@@ -2448,8 +2527,12 @@ body {
|
|
|
2448
2527
|
}
|
|
2449
2528
|
}
|
|
2450
2529
|
|
|
2451
|
-
.\[\&\:has\(\[role\=checkbox\]\)\]\:
|
|
2452
|
-
|
|
2530
|
+
.\[\&\:has\(\[role\=checkbox\]\)\]\:w-4:has([role=checkbox]) {
|
|
2531
|
+
width: 1rem;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-4:has([role=checkbox]) {
|
|
2535
|
+
padding-right: 1rem;
|
|
2453
2536
|
}
|
|
2454
2537
|
|
|
2455
2538
|
.\[\&\>tr\]\:last\:border-b-0:last-child>tr {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rovula/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"main": "dist/cjs/bundle.js",
|
|
5
5
|
"module": "dist/esm/bundle.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -74,6 +74,8 @@
|
|
|
74
74
|
"@radix-ui/react-label": "^2.0.2",
|
|
75
75
|
"@radix-ui/react-radio-group": "^1.1.3",
|
|
76
76
|
"@radix-ui/react-slot": "^1.0.2",
|
|
77
|
+
"@tanstack/react-table": "^8.17.3",
|
|
78
|
+
"@tanstack/react-virtual": "^3.5.0",
|
|
77
79
|
"@types/react": "^18.3.2",
|
|
78
80
|
"axios": "^1.6.4",
|
|
79
81
|
"class-variance-authority": "^0.7.0",
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import React, { FC, ReactElement } from "react";
|
|
1
|
+
import React, { FC, ReactElement, forwardRef } from "react";
|
|
2
2
|
import { buttonVariants } from "./Button.styles";
|
|
3
3
|
import { cn } from "@/utils/cn";
|
|
4
|
+
import { title } from "process";
|
|
5
|
+
import { ref } from "yup";
|
|
4
6
|
|
|
5
|
-
type ButtonProps = {
|
|
7
|
+
export type ButtonProps = {
|
|
6
8
|
title?: string;
|
|
7
9
|
size?: "sm" | "md" | "lg";
|
|
8
10
|
color?:
|
|
@@ -22,43 +24,49 @@ type ButtonProps = {
|
|
|
22
24
|
endIcon?: ReactElement;
|
|
23
25
|
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
24
26
|
|
|
25
|
-
const Button
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
27
|
+
const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
28
|
+
(
|
|
29
|
+
{
|
|
30
|
+
size = "md",
|
|
31
|
+
color = "primary",
|
|
32
|
+
variant = "solid",
|
|
33
|
+
title,
|
|
34
|
+
children,
|
|
35
|
+
startIcon,
|
|
36
|
+
endIcon,
|
|
37
|
+
disabled = false,
|
|
38
|
+
fullwidth = false,
|
|
39
|
+
isLoading = false,
|
|
40
|
+
className,
|
|
41
|
+
...props
|
|
42
|
+
},
|
|
43
|
+
ref
|
|
44
|
+
) => {
|
|
45
|
+
const isDisabled = disabled || isLoading;
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
47
|
+
return (
|
|
48
|
+
<button
|
|
49
|
+
type="button"
|
|
50
|
+
{...props}
|
|
51
|
+
ref={ref}
|
|
52
|
+
aria-disabled={isDisabled || undefined}
|
|
53
|
+
tabIndex={isDisabled ? -1 : 0}
|
|
54
|
+
className={cn(
|
|
55
|
+
buttonVariants({ size, color, variant, disabled, fullwidth }),
|
|
56
|
+
className
|
|
57
|
+
)}
|
|
58
|
+
disabled={isDisabled}
|
|
59
|
+
>
|
|
60
|
+
{
|
|
61
|
+
<>
|
|
62
|
+
{startIcon}
|
|
63
|
+
{children || title}
|
|
64
|
+
{endIcon}
|
|
65
|
+
</>
|
|
66
|
+
}
|
|
67
|
+
</button>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
);
|
|
63
71
|
|
|
64
72
|
export default Button;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import { DataTable } from "./DataTable";
|
|
4
|
+
import { ColumnDef } from "@tanstack/react-table";
|
|
5
|
+
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "Components/DataTable",
|
|
8
|
+
component: DataTable,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "fullscreen",
|
|
12
|
+
},
|
|
13
|
+
decorators: [
|
|
14
|
+
(Story) => (
|
|
15
|
+
<div
|
|
16
|
+
className="p-5 flex flex-1 h-full w-full "
|
|
17
|
+
style={{ height: "100vh" }}
|
|
18
|
+
>
|
|
19
|
+
<Story />
|
|
20
|
+
</div>
|
|
21
|
+
),
|
|
22
|
+
],
|
|
23
|
+
} satisfies Meta<typeof DataTable>;
|
|
24
|
+
|
|
25
|
+
export default meta;
|
|
26
|
+
|
|
27
|
+
const columns: ColumnDef<any>[] = [
|
|
28
|
+
{
|
|
29
|
+
accessorKey: "amount",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
accessorKey: "status",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
accessorKey: "email",
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
export const Default = {
|
|
40
|
+
args: {},
|
|
41
|
+
render: (args) => {
|
|
42
|
+
console.log("args ", args);
|
|
43
|
+
const props: typeof args = {
|
|
44
|
+
...args,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const data = new Array(20).fill(0).map((__, i) => ({
|
|
48
|
+
id: "m5gr84i9",
|
|
49
|
+
amount: i + 1,
|
|
50
|
+
status: "success",
|
|
51
|
+
email: "ken99@yahoo.com",
|
|
52
|
+
email1: "ken99@yahoo.com",
|
|
53
|
+
email2: "ken99@yahoo.com",
|
|
54
|
+
email3: "ken99@yahoo.com",
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<div className="flex flex-1 h-full flex-row gap-4 w-full">
|
|
59
|
+
<DataTable
|
|
60
|
+
columns={columns}
|
|
61
|
+
data={data}
|
|
62
|
+
onSorting={(sorting) => {
|
|
63
|
+
console.log("sorting ", sorting);
|
|
64
|
+
}}
|
|
65
|
+
fetchMoreData={() => {
|
|
66
|
+
console.log("fetchMoreData");
|
|
67
|
+
}}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
},
|
|
72
|
+
} satisfies StoryObj;
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ColumnDef,
|
|
3
|
+
ColumnFiltersState,
|
|
4
|
+
OnChangeFn,
|
|
5
|
+
SortingState,
|
|
6
|
+
VisibilityState,
|
|
7
|
+
flexRender,
|
|
8
|
+
getCoreRowModel,
|
|
9
|
+
getFilteredRowModel,
|
|
10
|
+
// getPaginationRowModel,
|
|
11
|
+
getSortedRowModel,
|
|
12
|
+
useReactTable,
|
|
13
|
+
} from "@tanstack/react-table";
|
|
14
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
ArrowDownIcon,
|
|
18
|
+
ArrowUpIcon,
|
|
19
|
+
ArrowsUpDownIcon,
|
|
20
|
+
ClipboardDocumentListIcon,
|
|
21
|
+
} from "@heroicons/react/16/solid";
|
|
22
|
+
|
|
23
|
+
import {
|
|
24
|
+
Table,
|
|
25
|
+
TableBody,
|
|
26
|
+
TableCell,
|
|
27
|
+
TableHead,
|
|
28
|
+
TableHeader,
|
|
29
|
+
TableRow,
|
|
30
|
+
} from "../Table/Table";
|
|
31
|
+
|
|
32
|
+
export interface DataTableProps<TData, TValue> {
|
|
33
|
+
columns: ColumnDef<TData, TValue>[];
|
|
34
|
+
data: TData[];
|
|
35
|
+
manualSorting?: boolean;
|
|
36
|
+
onSorting?: (sorting: SortingState) => void;
|
|
37
|
+
fetchMoreData?: () => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function DataTable<TData, TValue>({
|
|
41
|
+
data,
|
|
42
|
+
columns,
|
|
43
|
+
manualSorting = false,
|
|
44
|
+
onSorting,
|
|
45
|
+
fetchMoreData,
|
|
46
|
+
}: DataTableProps<TData, TValue>) {
|
|
47
|
+
const tableBodyRef = useRef<HTMLTableSectionElement>(null);
|
|
48
|
+
|
|
49
|
+
const [sorting, setSorting] = useState<SortingState>([]);
|
|
50
|
+
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
|
|
51
|
+
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
|
|
52
|
+
const [rowSelection, setRowSelection] = useState({});
|
|
53
|
+
|
|
54
|
+
const table = useReactTable({
|
|
55
|
+
data,
|
|
56
|
+
columns,
|
|
57
|
+
manualSorting,
|
|
58
|
+
onSortingChange: setSorting,
|
|
59
|
+
onColumnFiltersChange: setColumnFilters,
|
|
60
|
+
getCoreRowModel: getCoreRowModel(),
|
|
61
|
+
// getPaginationRowModel: getPaginationRowModel(),
|
|
62
|
+
getSortedRowModel: getSortedRowModel(),
|
|
63
|
+
getFilteredRowModel: getFilteredRowModel(),
|
|
64
|
+
onColumnVisibilityChange: setColumnVisibility,
|
|
65
|
+
onRowSelectionChange: setRowSelection,
|
|
66
|
+
state: {
|
|
67
|
+
sorting,
|
|
68
|
+
columnFilters,
|
|
69
|
+
columnVisibility,
|
|
70
|
+
rowSelection,
|
|
71
|
+
// pagination: {
|
|
72
|
+
// pageSize: 100,
|
|
73
|
+
// pageIndex: 0,
|
|
74
|
+
// },
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
onSorting?.(sorting);
|
|
80
|
+
}, [sorting, onSorting]);
|
|
81
|
+
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
const handleScroll = () => {
|
|
84
|
+
if (tableBodyRef.current) {
|
|
85
|
+
const { scrollTop, scrollHeight, clientHeight } = tableBodyRef.current;
|
|
86
|
+
if (scrollTop + clientHeight >= scrollHeight - 10) {
|
|
87
|
+
fetchMoreData?.();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const tableBodyElement = tableBodyRef.current;
|
|
93
|
+
if (tableBodyElement) {
|
|
94
|
+
tableBodyElement.addEventListener("scroll", handleScroll);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return () => {
|
|
98
|
+
if (tableBodyElement) {
|
|
99
|
+
tableBodyElement.removeEventListener("scroll", handleScroll);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}, [fetchMoreData]);
|
|
103
|
+
|
|
104
|
+
const isEmpty = table.getRowModel().rows?.length === 0;
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
<div className="flex w-full h-full rounded-xl overflow-hidden border border-primary-10">
|
|
108
|
+
<Table className={isEmpty ? "h-full" : ""} rootRef={tableBodyRef}>
|
|
109
|
+
<TableHeader className="sticky top-0">
|
|
110
|
+
{table.getHeaderGroups().map((headerGroup) => (
|
|
111
|
+
<TableRow key={headerGroup.id} className="">
|
|
112
|
+
{headerGroup.headers.map((header, i) => {
|
|
113
|
+
return (
|
|
114
|
+
<TableHead key={header.id}>
|
|
115
|
+
<div
|
|
116
|
+
className="flex flex-row items-center cursor-pointer"
|
|
117
|
+
onClick={header.column.getToggleSortingHandler()}
|
|
118
|
+
>
|
|
119
|
+
{header.isPlaceholder
|
|
120
|
+
? null
|
|
121
|
+
: flexRender(
|
|
122
|
+
header.column.columnDef.header,
|
|
123
|
+
header.getContext()
|
|
124
|
+
)}
|
|
125
|
+
{{
|
|
126
|
+
asc: <ArrowUpIcon className="ml-3 h-4 w-4" />,
|
|
127
|
+
desc: <ArrowDownIcon className="ml-3 h-4 w-4" />,
|
|
128
|
+
}[header.column.getIsSorted() as string] ??
|
|
129
|
+
(header.column.getCanSort() ? (
|
|
130
|
+
<ArrowsUpDownIcon className="ml-3 h-4 w-4 text-textcolor-grey-light" />
|
|
131
|
+
) : null)}
|
|
132
|
+
</div>
|
|
133
|
+
</TableHead>
|
|
134
|
+
);
|
|
135
|
+
})}
|
|
136
|
+
</TableRow>
|
|
137
|
+
))}
|
|
138
|
+
</TableHeader>
|
|
139
|
+
<TableBody className="overflow-y-scroll">
|
|
140
|
+
{!isEmpty ? (
|
|
141
|
+
table.getRowModel().rows.map((row) => (
|
|
142
|
+
<TableRow
|
|
143
|
+
key={row.id}
|
|
144
|
+
data-state={row.getIsSelected() && "selected"}
|
|
145
|
+
className=""
|
|
146
|
+
>
|
|
147
|
+
{row.getVisibleCells().map((cell) => (
|
|
148
|
+
<TableCell key={cell.id}>
|
|
149
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
150
|
+
</TableCell>
|
|
151
|
+
))}
|
|
152
|
+
</TableRow>
|
|
153
|
+
))
|
|
154
|
+
) : (
|
|
155
|
+
<TableRow className="h-full self-stretch">
|
|
156
|
+
<TableCell
|
|
157
|
+
colSpan={columns.length}
|
|
158
|
+
className="typography-body1 text-textcolor-grey-medium text-center h-full"
|
|
159
|
+
>
|
|
160
|
+
<div className="flex flex-1 h-full flex-col items-center justify-center gap-3">
|
|
161
|
+
<ClipboardDocumentListIcon className="w-8 text-secondary-120" />
|
|
162
|
+
There is no information yet.
|
|
163
|
+
</div>
|
|
164
|
+
</TableCell>
|
|
165
|
+
</TableRow>
|
|
166
|
+
)}
|
|
167
|
+
</TableBody>
|
|
168
|
+
</Table>
|
|
169
|
+
</div>
|
|
170
|
+
);
|
|
171
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { useRef } from "react";
|
|
2
2
|
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
-
import Dropdown from "./Dropdown";
|
|
3
|
+
import Dropdown, { Options } from "./Dropdown";
|
|
4
|
+
import Button from "../Button/Button";
|
|
5
|
+
import { cn } from "@/utils/cn";
|
|
4
6
|
|
|
5
7
|
// More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
|
|
6
8
|
const meta = {
|
|
@@ -22,7 +24,7 @@ const meta = {
|
|
|
22
24
|
|
|
23
25
|
export default meta;
|
|
24
26
|
|
|
25
|
-
const options = new Array(100).fill("").map((__, index) => ({
|
|
27
|
+
const options: Options[] = new Array(100).fill("").map((__, index) => ({
|
|
26
28
|
value: `option${index + 1}`,
|
|
27
29
|
label: `Option ${index + 1}`,
|
|
28
30
|
}));
|
|
@@ -47,3 +49,85 @@ export const Default = {
|
|
|
47
49
|
);
|
|
48
50
|
},
|
|
49
51
|
} satisfies StoryObj;
|
|
52
|
+
|
|
53
|
+
const DropdownWithRef = (props: any) => {
|
|
54
|
+
const inputRef = useRef<HTMLInputElement | null>(null);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Dropdown
|
|
58
|
+
id="1"
|
|
59
|
+
size="lg"
|
|
60
|
+
{...props}
|
|
61
|
+
ref={inputRef}
|
|
62
|
+
labelClassName="peer-focus:bg-red-500"
|
|
63
|
+
onKeyDown={(e) => {
|
|
64
|
+
if (e.code === "Enter") {
|
|
65
|
+
inputRef.current?.blur?.();
|
|
66
|
+
}
|
|
67
|
+
}}
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const WithRef = {
|
|
73
|
+
args: {
|
|
74
|
+
label: "Choose an option:",
|
|
75
|
+
fullwidth: true,
|
|
76
|
+
options,
|
|
77
|
+
filterMode: true,
|
|
78
|
+
},
|
|
79
|
+
render: (args) => {
|
|
80
|
+
console.log("args ", args);
|
|
81
|
+
const props: typeof args = {
|
|
82
|
+
...args,
|
|
83
|
+
};
|
|
84
|
+
return (
|
|
85
|
+
<div className="flex flex-row gap-4 w-full">
|
|
86
|
+
<DropdownWithRef id="1" size="lg" options={options} {...args} />\
|
|
87
|
+
</div>
|
|
88
|
+
);
|
|
89
|
+
},
|
|
90
|
+
} satisfies StoryObj;
|
|
91
|
+
|
|
92
|
+
const customOptions: Options[] = new Array(100).fill("").map((__, index) => ({
|
|
93
|
+
value: `option${index + 1}`,
|
|
94
|
+
label: `Option ${index + 1}`,
|
|
95
|
+
renderLabel(config) {
|
|
96
|
+
return (
|
|
97
|
+
<div
|
|
98
|
+
className={cn(config, "w-full flex justify-between")}
|
|
99
|
+
onMouseDown={config.handleOnClick}
|
|
100
|
+
>
|
|
101
|
+
<span>Test custom</span>
|
|
102
|
+
<Button
|
|
103
|
+
onMouseDown={(e) => {
|
|
104
|
+
// e.stopPropagation();
|
|
105
|
+
alert("SSS");
|
|
106
|
+
}}
|
|
107
|
+
>
|
|
108
|
+
Add action
|
|
109
|
+
</Button>
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
},
|
|
113
|
+
}));
|
|
114
|
+
|
|
115
|
+
export const CustomOption = {
|
|
116
|
+
args: {
|
|
117
|
+
label: "Choose an option:",
|
|
118
|
+
fullwidth: true,
|
|
119
|
+
options: customOptions,
|
|
120
|
+
filterMode: true,
|
|
121
|
+
},
|
|
122
|
+
render: (args) => {
|
|
123
|
+
console.log("args ", args);
|
|
124
|
+
const props: typeof args = {
|
|
125
|
+
...args,
|
|
126
|
+
};
|
|
127
|
+
return (
|
|
128
|
+
<div className="flex flex-row gap-4 w-full">
|
|
129
|
+
<DropdownWithRef id="1" size="lg" options={options} {...args} />\
|
|
130
|
+
</div>
|
|
131
|
+
);
|
|
132
|
+
},
|
|
133
|
+
} satisfies StoryObj;
|