@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.
Files changed (59) hide show
  1. package/dist/cjs/bundle.css +66 -2
  2. package/dist/cjs/bundle.js +23 -1
  3. package/dist/cjs/bundle.js.map +1 -1
  4. package/dist/cjs/types/components/Button/Button.d.ts +14 -3
  5. package/dist/cjs/types/components/Button/Buttons.stories.d.ts +8 -6
  6. package/dist/cjs/types/components/DataTable/DataTable.d.ts +9 -0
  7. package/dist/cjs/types/components/DataTable/DataTable.stories.d.ts +22 -0
  8. package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +29 -3
  9. package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +31 -30
  10. package/dist/cjs/types/components/Label/Label.stories.d.ts +1 -1
  11. package/dist/cjs/types/components/RadioGroup/RadioGroup.stories.d.ts +1 -1
  12. package/dist/cjs/types/components/Table/Table.d.ts +3 -1
  13. package/dist/cjs/types/components/Table/Table.stories.d.ts +4 -1
  14. package/dist/cjs/types/components/Text/Text.d.ts +3 -3
  15. package/dist/cjs/types/components/Text/Text.stories.d.ts +3 -9
  16. package/dist/cjs/types/components/TextInput/TextInput.d.ts +20 -2
  17. package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +28 -1
  18. package/dist/cjs/types/index.d.ts +4 -0
  19. package/dist/components/Button/Button.js +4 -3
  20. package/dist/components/DataTable/DataTable.js +71 -0
  21. package/dist/components/DataTable/DataTable.stories.js +57 -0
  22. package/dist/components/Dropdown/Dropdown.js +15 -5
  23. package/dist/components/Dropdown/Dropdown.stories.js +48 -0
  24. package/dist/components/Table/Table.js +6 -6
  25. package/dist/components/Text/Text.js +3 -2
  26. package/dist/components/TextInput/TextInput.js +5 -7
  27. package/dist/components/TextInput/TextInput.stories.js +22 -0
  28. package/dist/esm/bundle.css +66 -2
  29. package/dist/esm/bundle.js +23 -1
  30. package/dist/esm/bundle.js.map +1 -1
  31. package/dist/esm/types/components/Button/Button.d.ts +14 -3
  32. package/dist/esm/types/components/Button/Buttons.stories.d.ts +8 -6
  33. package/dist/esm/types/components/DataTable/DataTable.d.ts +9 -0
  34. package/dist/esm/types/components/DataTable/DataTable.stories.d.ts +22 -0
  35. package/dist/esm/types/components/Dropdown/Dropdown.d.ts +29 -3
  36. package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +31 -30
  37. package/dist/esm/types/components/Label/Label.stories.d.ts +1 -1
  38. package/dist/esm/types/components/RadioGroup/RadioGroup.stories.d.ts +1 -1
  39. package/dist/esm/types/components/Table/Table.d.ts +3 -1
  40. package/dist/esm/types/components/Table/Table.stories.d.ts +4 -1
  41. package/dist/esm/types/components/Text/Text.d.ts +3 -3
  42. package/dist/esm/types/components/Text/Text.stories.d.ts +3 -9
  43. package/dist/esm/types/components/TextInput/TextInput.d.ts +20 -2
  44. package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +28 -1
  45. package/dist/esm/types/index.d.ts +4 -0
  46. package/dist/index.d.ts +74 -8
  47. package/dist/index.js +1 -0
  48. package/dist/src/theme/global.css +85 -2
  49. package/package.json +3 -1
  50. package/src/components/Button/Button.tsx +47 -39
  51. package/src/components/DataTable/DataTable.stories.tsx +72 -0
  52. package/src/components/DataTable/DataTable.tsx +171 -0
  53. package/src/components/Dropdown/Dropdown.stories.tsx +87 -3
  54. package/src/components/Dropdown/Dropdown.tsx +147 -109
  55. package/src/components/Table/Table.tsx +17 -8
  56. package/src/components/Text/Text.tsx +21 -19
  57. package/src/components/TextInput/TextInput.stories.tsx +46 -1
  58. package/src/components/TextInput/TextInput.tsx +7 -7
  59. 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\]\)\]\:pr-0:has([role=checkbox]) {
2452
- 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;
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.10",
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: FC<ButtonProps> = ({
26
- size = "md",
27
- color = "primary",
28
- variant = "solid",
29
- title,
30
- children,
31
- startIcon,
32
- endIcon,
33
- disabled = false,
34
- fullwidth = false,
35
- isLoading = false,
36
- className,
37
- ...props
38
- }) => {
39
- const isDisabled = disabled || isLoading;
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
- return (
42
- <button
43
- type="button"
44
- {...props}
45
- aria-disabled={isDisabled || undefined}
46
- tabIndex={isDisabled ? -1 : 0}
47
- className={cn(
48
- buttonVariants({ size, color, variant, disabled, fullwidth }),
49
- className
50
- )}
51
- disabled={isDisabled}
52
- >
53
- {
54
- <>
55
- {startIcon}
56
- {children || title}
57
- {endIcon}
58
- </>
59
- }
60
- </button>
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;