@rovula/ui 0.0.11 → 0.0.13

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.
Files changed (35) hide show
  1. package/dist/cjs/bundle.css +55 -5
  2. package/dist/cjs/bundle.js +23 -1
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/DataTable/DataTable.d.ts +6 -11
  5. package/dist/cjs/types/components/DataTable/DataTable.stories.d.ts +3 -0
  6. package/dist/cjs/types/components/Table/Table.d.ts +3 -1
  7. package/dist/cjs/types/components/Table/Table.stories.d.ts +4 -1
  8. package/dist/cjs/types/index.d.ts +2 -1
  9. package/dist/components/DataTable/DataTable.js +62 -23
  10. package/dist/components/DataTable/DataTable.stories.js +16 -25
  11. package/dist/components/Dropdown/Dropdown.js +39 -2
  12. package/dist/components/Dropdown/Dropdown.stories.js +29 -4
  13. package/dist/components/Table/Table.js +6 -6
  14. package/dist/esm/bundle.css +55 -5
  15. package/dist/esm/bundle.js +23 -1
  16. package/dist/esm/bundle.js.map +1 -1
  17. package/dist/esm/types/components/DataTable/DataTable.d.ts +6 -11
  18. package/dist/esm/types/components/DataTable/DataTable.stories.d.ts +3 -0
  19. package/dist/esm/types/components/Table/Table.d.ts +3 -1
  20. package/dist/esm/types/components/Table/Table.stories.d.ts +4 -1
  21. package/dist/esm/types/index.d.ts +2 -1
  22. package/dist/index.d.ts +14 -2
  23. package/dist/index.js +1 -0
  24. package/dist/src/theme/global.css +71 -6
  25. package/package.json +2 -1
  26. package/src/components/DataTable/DataTable.stories.tsx +26 -30
  27. package/src/components/DataTable/DataTable.tsx +111 -45
  28. package/src/components/Dropdown/Dropdown.stories.tsx +25 -3
  29. package/src/components/Dropdown/Dropdown.tsx +61 -2
  30. package/src/components/Table/Table.tsx +17 -8
  31. package/src/index.ts +2 -1
  32. package/dist/cjs/types/components/ui/table.d.ts +0 -10
  33. package/dist/components/ui/table.js +0 -66
  34. package/dist/esm/types/components/ui/table.d.ts +0 -10
  35. package/src/components/ui/table.tsx +0 -117
@@ -1,14 +1,9 @@
1
- import { ColumnDef } from "@tanstack/react-table";
2
- export type Payment = {
3
- id: string;
4
- amount: number;
5
- status: "pending" | "processing" | "success" | "failed";
6
- email: string;
7
- };
8
- export declare const columns: ColumnDef<Payment>[];
9
- interface DataTableProps<TData, TValue> {
1
+ import { ColumnDef, SortingState } from "@tanstack/react-table";
2
+ export interface DataTableProps<TData, TValue> {
10
3
  columns: ColumnDef<TData, TValue>[];
11
4
  data: TData[];
5
+ manualSorting?: boolean;
6
+ onSorting?: (sorting: SortingState) => void;
7
+ fetchMoreData?: () => void;
12
8
  }
13
- export declare function DataTable<TData, TValue>({ columns, data, }: DataTableProps<TData, TValue>): import("react/jsx-runtime").JSX.Element;
14
- export {};
9
+ export declare function DataTable<TData, TValue>({ data, columns, manualSorting, onSorting, fetchMoreData, }: DataTableProps<TData, TValue>): import("react/jsx-runtime").JSX.Element;
@@ -10,6 +10,9 @@ declare const meta: {
10
10
  decorators: ((Story: import("@storybook/types").PartialStoryFn<import("@storybook/react").ReactRenderer, {
11
11
  columns: ColumnDef<unknown, unknown>[];
12
12
  data: unknown[];
13
+ manualSorting?: boolean | undefined;
14
+ onSorting?: ((sorting: import("@tanstack/react-table").SortingState) => void) | undefined;
15
+ fetchMoreData?: (() => void) | undefined;
13
16
  }>) => import("react/jsx-runtime").JSX.Element)[];
14
17
  };
15
18
  export default meta;
@@ -1,5 +1,7 @@
1
1
  import * as React from "react";
2
- declare const Table: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
2
+ declare const Table: React.ForwardRefExoticComponent<{
3
+ rootRef?: React.LegacyRef<HTMLDivElement> | undefined;
4
+ } & React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
3
5
  declare const TableHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
4
6
  declare const TableBody: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
5
7
  declare const TableFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
@@ -1,12 +1,15 @@
1
1
  import React from "react";
2
2
  declare const meta: {
3
3
  title: string;
4
- component: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
4
+ component: React.ForwardRefExoticComponent<{
5
+ rootRef?: React.LegacyRef<HTMLDivElement> | undefined;
6
+ } & React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
5
7
  tags: string[];
6
8
  parameters: {
7
9
  layout: string;
8
10
  };
9
11
  decorators: ((Story: import("@storybook/types").PartialStoryFn<import("@storybook/react").ReactRenderer, {
12
+ rootRef?: React.LegacyRef<HTMLDivElement> | undefined;
10
13
  defaultChecked?: boolean | undefined;
11
14
  defaultValue?: string | number | readonly string[] | undefined;
12
15
  suppressContentEditableWarning?: boolean | undefined;
@@ -8,10 +8,11 @@ export { Checkbox } from "./components/Checkbox/Checkbox";
8
8
  export { Label } from "./components/Label/Label";
9
9
  export { Input } from "./components/Input/Input";
10
10
  export * from "./components/Table/Table";
11
+ export * from "./components/DataTable/DataTable";
11
12
  export * from "./components/Dialog/Dialog";
12
13
  export * from "./components/AlertDialog/AlertDialog";
13
14
  export type { ButtonProps } from "./components/Button/Button";
14
15
  export type { InputProps } from "./components/TextInput/TextInput";
15
- export type { DropdownProps } from "./components/Dropdown/Dropdown";
16
+ export type { DropdownProps, Options } from "./components/Dropdown/Dropdown";
16
17
  export { resloveTimestamp, getStartDateOfDay, getEndDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, } from "./utils/datetime";
17
18
  export { cn } from "./utils/cn";
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ import * as class_variance_authority_dist_types from 'class-variance-authority/d
5
5
  import * as LabelPrimitive from '@radix-ui/react-label';
6
6
  import { VariantProps } from 'class-variance-authority';
7
7
  import * as react_jsx_runtime from 'react/jsx-runtime';
8
+ import { ColumnDef, SortingState } from '@tanstack/react-table';
8
9
  import * as DialogPrimitive from '@radix-ui/react-dialog';
9
10
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
10
11
  import { ClassValue } from 'clsx';
@@ -152,7 +153,9 @@ interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
152
153
  }
153
154
  declare const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HTMLInputElement>>;
154
155
 
155
- declare const Table: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
156
+ declare const Table: React.ForwardRefExoticComponent<{
157
+ rootRef?: React.LegacyRef<HTMLDivElement> | undefined;
158
+ } & React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
156
159
  declare const TableHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
157
160
  declare const TableBody: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
158
161
  declare const TableFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
@@ -161,6 +164,15 @@ declare const TableHead: React.ForwardRefExoticComponent<React.ThHTMLAttributes<
161
164
  declare const TableCell: React.ForwardRefExoticComponent<React.TdHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>;
162
165
  declare const TableCaption: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableCaptionElement> & React.RefAttributes<HTMLTableCaptionElement>>;
163
166
 
167
+ interface DataTableProps<TData, TValue> {
168
+ columns: ColumnDef<TData, TValue>[];
169
+ data: TData[];
170
+ manualSorting?: boolean;
171
+ onSorting?: (sorting: SortingState) => void;
172
+ fetchMoreData?: () => void;
173
+ }
174
+ declare function DataTable<TData, TValue>({ data, columns, manualSorting, onSorting, fetchMoreData, }: DataTableProps<TData, TValue>): react_jsx_runtime.JSX.Element;
175
+
164
176
  declare const Dialog: React.FC<DialogPrimitive.DialogProps>;
165
177
  declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
166
178
  declare const DialogPortal: React.FC<DialogPrimitive.DialogPortalProps>;
@@ -207,4 +219,4 @@ declare const getTimestampUTC: (date: Date) => number;
207
219
 
208
220
  declare function cn(...inputs: ClassValue[]): string;
209
221
 
210
- export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, type ButtonProps, Checkbox, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, type DropdownProps, Input, type InputProps$1 as InputProps, Label, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextInput, cn, getEndDateOfDay, getStartDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, resloveTimestamp };
222
+ export { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, type ButtonProps, Checkbox, DataTable, type DataTableProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Dropdown, type DropdownProps, Input, type InputProps$1 as InputProps, Label, type Options, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, Text, TextInput, cn, getEndDateOfDay, getStartDateOfDay, getStartEndTimestampOfDay, getTimestampUTC, resloveTimestamp };
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ export { Checkbox } from "./components/Checkbox/Checkbox";
10
10
  export { Label } from "./components/Label/Label";
11
11
  export { Input } from "./components/Input/Input";
12
12
  export * from "./components/Table/Table";
13
+ export * from "./components/DataTable/DataTable";
13
14
  export * from "./components/Dialog/Dialog";
14
15
  export * from "./components/AlertDialog/AlertDialog";
15
16
  // UTILS
@@ -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
  }
@@ -1030,10 +1042,6 @@ body {
1030
1042
  height: 3rem;
1031
1043
  }
1032
1044
 
1033
- .h-24 {
1034
- height: 6rem;
1035
- }
1036
-
1037
1045
  .h-4 {
1038
1046
  height: 1rem;
1039
1047
  }
@@ -1042,6 +1050,10 @@ body {
1042
1050
  height: 54px;
1043
1051
  }
1044
1052
 
1053
+ .h-full {
1054
+ height: 100%;
1055
+ }
1056
+
1045
1057
  .max-h-60 {
1046
1058
  max-height: 15rem;
1047
1059
  }
@@ -1050,6 +1062,10 @@ body {
1050
1062
  width: 1rem;
1051
1063
  }
1052
1064
 
1065
+ .w-8 {
1066
+ width: 2rem;
1067
+ }
1068
+
1053
1069
  .w-\[100px\] {
1054
1070
  width: 100px;
1055
1071
  }
@@ -1078,6 +1094,10 @@ body {
1078
1094
  max-width: 32rem;
1079
1095
  }
1080
1096
 
1097
+ .flex-1 {
1098
+ flex: 1 1 0%;
1099
+ }
1100
+
1081
1101
  .shrink-0 {
1082
1102
  flex-shrink: 0;
1083
1103
  }
@@ -1086,6 +1106,10 @@ body {
1086
1106
  caption-side: bottom;
1087
1107
  }
1088
1108
 
1109
+ .border-collapse {
1110
+ border-collapse: collapse;
1111
+ }
1112
+
1089
1113
  .translate-x-\[-50\%\] {
1090
1114
  --tw-translate-x: -50%;
1091
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));
@@ -1204,10 +1228,18 @@ body {
1204
1228
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
1205
1229
  }
1206
1230
 
1231
+ .self-stretch {
1232
+ align-self: stretch;
1233
+ }
1234
+
1207
1235
  .overflow-auto {
1208
1236
  overflow: auto;
1209
1237
  }
1210
1238
 
1239
+ .overflow-hidden {
1240
+ overflow: hidden;
1241
+ }
1242
+
1211
1243
  .overflow-x-auto {
1212
1244
  overflow-x: auto;
1213
1245
  }
@@ -1216,6 +1248,10 @@ body {
1216
1248
  overflow-y: auto;
1217
1249
  }
1218
1250
 
1251
+ .overflow-y-scroll {
1252
+ overflow-y: scroll;
1253
+ }
1254
+
1219
1255
  .whitespace-nowrap {
1220
1256
  white-space: nowrap;
1221
1257
  }
@@ -1406,6 +1442,11 @@ body {
1406
1442
  background-color: rgb(var(--secondary-110) / var(--tw-bg-opacity));
1407
1443
  }
1408
1444
 
1445
+ .bg-secondary-80 {
1446
+ --tw-bg-opacity: 1;
1447
+ background-color: rgb(var(--secondary-80) / var(--tw-bg-opacity));
1448
+ }
1449
+
1409
1450
  .bg-success {
1410
1451
  --tw-bg-opacity: 1;
1411
1452
  background-color: rgb(var(--success-default) / var(--tw-bg-opacity));
@@ -1522,6 +1563,11 @@ body {
1522
1563
  padding-bottom: 0.5rem;
1523
1564
  }
1524
1565
 
1566
+ .py-3 {
1567
+ padding-top: 0.75rem;
1568
+ padding-bottom: 0.75rem;
1569
+ }
1570
+
1525
1571
  .py-4 {
1526
1572
  padding-top: 1rem;
1527
1573
  padding-bottom: 1rem;
@@ -1778,6 +1824,11 @@ body {
1778
1824
  color: rgb(var(--secondary-110) / var(--tw-text-opacity));
1779
1825
  }
1780
1826
 
1827
+ .text-secondary-120 {
1828
+ --tw-text-opacity: 1;
1829
+ color: rgb(var(--secondary-120) / var(--tw-text-opacity));
1830
+ }
1831
+
1781
1832
  .text-secondary-130 {
1782
1833
  --tw-text-opacity: 1;
1783
1834
  color: rgb(var(--secondary-130) / var(--tw-text-opacity));
@@ -1823,6 +1874,11 @@ body {
1823
1874
  color: rgb(var(--text-grey-light) / var(--tw-text-opacity));
1824
1875
  }
1825
1876
 
1877
+ .text-textcolor-grey-medium {
1878
+ --tw-text-opacity: 1;
1879
+ color: rgb(var(--text-grey-medium) / var(--tw-text-opacity));
1880
+ }
1881
+
1826
1882
  .text-warning {
1827
1883
  --tw-text-opacity: 1;
1828
1884
  color: rgb(var(--warning-default) / var(--tw-text-opacity));
@@ -2429,6 +2485,11 @@ body {
2429
2485
  background-color: rgb(var(--primary-default) / var(--tw-bg-opacity));
2430
2486
  }
2431
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
+
2432
2493
  .data-\[state\=checked\]\:text-primary-foreground[data-state=checked] {
2433
2494
  --tw-text-opacity: 1;
2434
2495
  color: rgb(var(--primary-foreground) / var(--tw-text-opacity));
@@ -2466,8 +2527,12 @@ body {
2466
2527
  }
2467
2528
  }
2468
2529
 
2469
- .\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]) {
2470
- padding-right: 0px;
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;
2471
2536
  }
2472
2537
 
2473
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.11",
3
+ "version": "0.0.13",
4
4
  "main": "dist/cjs/bundle.js",
5
5
  "module": "dist/esm/bundle.js",
6
6
  "types": "dist/index.d.ts",
@@ -75,6 +75,7 @@
75
75
  "@radix-ui/react-radio-group": "^1.1.3",
76
76
  "@radix-ui/react-slot": "^1.0.2",
77
77
  "@tanstack/react-table": "^8.17.3",
78
+ "@tanstack/react-virtual": "^3.5.0",
78
79
  "@types/react": "^18.3.2",
79
80
  "axios": "^1.6.4",
80
81
  "class-variance-authority": "^0.7.0",
@@ -1,9 +1,5 @@
1
1
  import React from "react";
2
2
  import type { Meta, StoryObj } from "@storybook/react";
3
-
4
- import Button from "../Button/Button";
5
- import { Label } from "../Label/Label";
6
- import { Input } from "../Input/Input";
7
3
  import { DataTable } from "./DataTable";
8
4
  import { ColumnDef } from "@tanstack/react-table";
9
5
 
@@ -16,7 +12,10 @@ const meta = {
16
12
  },
17
13
  decorators: [
18
14
  (Story) => (
19
- <div className="p-5 flex w-full">
15
+ <div
16
+ className="p-5 flex flex-1 h-full w-full "
17
+ style={{ height: "100vh" }}
18
+ >
20
19
  <Story />
21
20
  </div>
22
21
  ),
@@ -28,16 +27,6 @@ export default meta;
28
27
  const columns: ColumnDef<any>[] = [
29
28
  {
30
29
  accessorKey: "amount",
31
- header: () => <div className="text-right">Amount</div>,
32
- cell: ({ row }: any) => {
33
- const amount = parseFloat(row.getValue("amount"));
34
- const formatted = new Intl.NumberFormat("en-US", {
35
- style: "currency",
36
- currency: "USD",
37
- }).format(amount);
38
-
39
- return <div className="text-right font-medium">{formatted}</div>;
40
- },
41
30
  },
42
31
  {
43
32
  accessorKey: "status",
@@ -48,28 +37,35 @@ const columns: ColumnDef<any>[] = [
48
37
  ];
49
38
 
50
39
  export const Default = {
51
- args: {
52
- // label: "Lorem Ipsum",
53
- // value: "Lorem Ipsum",
54
- // fullwidth: true,
55
- },
40
+ args: {},
56
41
  render: (args) => {
57
42
  console.log("args ", args);
58
43
  const props: typeof args = {
59
44
  ...args,
60
45
  };
61
- const data = [
62
- {
63
- id: "728ed52f",
64
- amount: 100,
65
- status: "pending",
66
- email: "m@example.com",
67
- },
68
- ];
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
+ }));
69
56
 
70
57
  return (
71
- <div className="flex flex-row gap-4 w-full">
72
- <DataTable columns={columns} data={data} />
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
+ />
73
69
  </div>
74
70
  );
75
71
  },
@@ -1,36 +1,24 @@
1
- "use client";
2
-
3
- import React from "react";
4
1
  import {
5
2
  ColumnDef,
3
+ ColumnFiltersState,
4
+ OnChangeFn,
5
+ SortingState,
6
+ VisibilityState,
6
7
  flexRender,
7
8
  getCoreRowModel,
9
+ getFilteredRowModel,
10
+ // getPaginationRowModel,
11
+ getSortedRowModel,
8
12
  useReactTable,
9
13
  } from "@tanstack/react-table";
14
+ import React, { useEffect, useRef, useState } from "react";
10
15
 
11
- // This type is used to define the shape of our data.
12
- // You can use a Zod schema here if you want.
13
- export type Payment = {
14
- id: string;
15
- amount: number;
16
- status: "pending" | "processing" | "success" | "failed";
17
- email: string;
18
- };
19
-
20
- export const columns: ColumnDef<Payment>[] = [
21
- {
22
- accessorKey: "status",
23
- header: "Status",
24
- },
25
- {
26
- accessorKey: "email",
27
- header: "Email",
28
- },
29
- {
30
- accessorKey: "amount",
31
- header: "Amount",
32
- },
33
- ];
16
+ import {
17
+ ArrowDownIcon,
18
+ ArrowUpIcon,
19
+ ArrowsUpDownIcon,
20
+ ClipboardDocumentListIcon,
21
+ } from "@heroicons/react/16/solid";
34
22
 
35
23
  import {
36
24
  Table,
@@ -39,50 +27,122 @@ import {
39
27
  TableHead,
40
28
  TableHeader,
41
29
  TableRow,
42
- } from "@/components/ui/table";
30
+ } from "../Table/Table";
43
31
 
44
- interface DataTableProps<TData, TValue> {
32
+ export interface DataTableProps<TData, TValue> {
45
33
  columns: ColumnDef<TData, TValue>[];
46
34
  data: TData[];
35
+ manualSorting?: boolean;
36
+ onSorting?: (sorting: SortingState) => void;
37
+ fetchMoreData?: () => void;
47
38
  }
48
39
 
49
40
  export function DataTable<TData, TValue>({
50
- columns,
51
41
  data,
42
+ columns,
43
+ manualSorting = false,
44
+ onSorting,
45
+ fetchMoreData,
52
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
+
53
54
  const table = useReactTable({
54
55
  data,
55
56
  columns,
57
+ manualSorting,
58
+ onSortingChange: setSorting,
59
+ onColumnFiltersChange: setColumnFilters,
56
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
+ },
57
76
  });
58
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
+
59
106
  return (
60
- <div className="rounded-md border">
61
- <Table>
62
- <TableHeader>
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">
63
110
  {table.getHeaderGroups().map((headerGroup) => (
64
- <TableRow key={headerGroup.id}>
65
- {headerGroup.headers.map((header) => {
111
+ <TableRow key={headerGroup.id} className="">
112
+ {headerGroup.headers.map((header, i) => {
66
113
  return (
67
114
  <TableHead key={header.id}>
68
- {header.isPlaceholder
69
- ? null
70
- : flexRender(
71
- header.column.columnDef.header,
72
- header.getContext()
73
- )}
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>
74
133
  </TableHead>
75
134
  );
76
135
  })}
77
136
  </TableRow>
78
137
  ))}
79
138
  </TableHeader>
80
- <TableBody>
81
- {table.getRowModel().rows?.length ? (
139
+ <TableBody className="overflow-y-scroll">
140
+ {!isEmpty ? (
82
141
  table.getRowModel().rows.map((row) => (
83
142
  <TableRow
84
143
  key={row.id}
85
144
  data-state={row.getIsSelected() && "selected"}
145
+ className=""
86
146
  >
87
147
  {row.getVisibleCells().map((cell) => (
88
148
  <TableCell key={cell.id}>
@@ -92,9 +152,15 @@ export function DataTable<TData, TValue>({
92
152
  </TableRow>
93
153
  ))
94
154
  ) : (
95
- <TableRow>
96
- <TableCell colSpan={columns.length} className="h-24 text-center">
97
- No results.
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>
98
164
  </TableCell>
99
165
  </TableRow>
100
166
  )}