@dmsi/wedgekit-react 0.0.2

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 (263) hide show
  1. package/README.md +35 -0
  2. package/dist/chunk-27KIIUAR.js +59 -0
  3. package/dist/chunk-2G2E2JMA.js +123 -0
  4. package/dist/chunk-4C66DLIJ.js +51 -0
  5. package/dist/chunk-4RD5ZF2V.js +55 -0
  6. package/dist/chunk-4RJKB7LC.js +14 -0
  7. package/dist/chunk-4T7F5BZZ.js +26 -0
  8. package/dist/chunk-5GOBP2JS.js +53 -0
  9. package/dist/chunk-6ZY524ID.js +42 -0
  10. package/dist/chunk-AWQSSKCK.js +32 -0
  11. package/dist/chunk-BNHSAFMP.js +93 -0
  12. package/dist/chunk-BWRHL2AG.js +439 -0
  13. package/dist/chunk-DKKYR6DS.js +132 -0
  14. package/dist/chunk-E5ALT5W7.js +182 -0
  15. package/dist/chunk-FY7PTP6E.js +322 -0
  16. package/dist/chunk-GTCSRHPF.js +119 -0
  17. package/dist/chunk-I2UVVKQI.js +12 -0
  18. package/dist/chunk-IGQVA7SC.js +41 -0
  19. package/dist/chunk-K3IKUSZW.js +59 -0
  20. package/dist/chunk-KENSVWOY.js +151 -0
  21. package/dist/chunk-KX3O6GJ6.js +138 -0
  22. package/dist/chunk-L4UM372R.js +253 -0
  23. package/dist/chunk-ORMEWXMH.js +37 -0
  24. package/dist/chunk-Q3FKEKIN.js +23 -0
  25. package/dist/chunk-SEKKGFM6.js +28 -0
  26. package/dist/chunk-SY3HT54E.js +91 -0
  27. package/dist/chunk-TAW5ZZ4Z.js +346 -0
  28. package/dist/chunk-TRUPPHBQ.js +109 -0
  29. package/dist/chunk-TU55CHXU.js +30 -0
  30. package/dist/chunk-TWZZB4WO.js +114 -0
  31. package/dist/chunk-TYI74BSP.js +62 -0
  32. package/dist/chunk-U42SKNR6.js +104 -0
  33. package/dist/chunk-UU3FA6LV.js +72 -0
  34. package/dist/chunk-WVUIIBRR.js +51 -0
  35. package/dist/chunk-XUIPGYP5.js +39 -0
  36. package/dist/chunk-Z4UCFUF7.js +299 -0
  37. package/dist/components/Breadcrumbs.cjs +376 -0
  38. package/dist/components/Breadcrumbs.js +90 -0
  39. package/dist/components/Button.cjs +319 -0
  40. package/dist/components/Button.js +8 -0
  41. package/dist/components/CalendarRange.cjs +520 -0
  42. package/dist/components/CalendarRange.js +13 -0
  43. package/dist/components/Caption.cjs +283 -0
  44. package/dist/components/Caption.js +80 -0
  45. package/dist/components/Checkbox.cjs +378 -0
  46. package/dist/components/Checkbox.js +11 -0
  47. package/dist/components/ContentTab.cjs +382 -0
  48. package/dist/components/ContentTab.js +10 -0
  49. package/dist/components/ContentTabs.cjs +472 -0
  50. package/dist/components/ContentTabs.js +98 -0
  51. package/dist/components/DMSiLogo.cjs +79 -0
  52. package/dist/components/DMSiLogo.js +56 -0
  53. package/dist/components/DataGrid.cjs +3113 -0
  54. package/dist/components/DataGrid.js +758 -0
  55. package/dist/components/DataGridCell.cjs +1907 -0
  56. package/dist/components/DataGridCell.js +24 -0
  57. package/dist/components/DataTable.cjs +791 -0
  58. package/dist/components/DataTable.js +720 -0
  59. package/dist/components/DateInput.cjs +1130 -0
  60. package/dist/components/DateInput.js +170 -0
  61. package/dist/components/DateRangeInput.cjs +1131 -0
  62. package/dist/components/DateRangeInput.js +171 -0
  63. package/dist/components/DebugJson.cjs +50 -0
  64. package/dist/components/DebugJson.js +27 -0
  65. package/dist/components/Display.cjs +234 -0
  66. package/dist/components/Display.js +12 -0
  67. package/dist/components/EditingContext.cjs +73 -0
  68. package/dist/components/EditingContext.js +35 -0
  69. package/dist/components/FilterGroup.cjs +1431 -0
  70. package/dist/components/FilterGroup.js +231 -0
  71. package/dist/components/FullViewportBox.cjs +35 -0
  72. package/dist/components/FullViewportBox.js +12 -0
  73. package/dist/components/Grid.cjs +69 -0
  74. package/dist/components/Grid.js +36 -0
  75. package/dist/components/GridContainer.cjs +125 -0
  76. package/dist/components/GridContainer.js +92 -0
  77. package/dist/components/Heading.cjs +238 -0
  78. package/dist/components/Heading.js +14 -0
  79. package/dist/components/HorizontalDivider.cjs +33 -0
  80. package/dist/components/HorizontalDivider.js +10 -0
  81. package/dist/components/Icon.cjs +98 -0
  82. package/dist/components/Icon.js +7 -0
  83. package/dist/components/Input.cjs +672 -0
  84. package/dist/components/Input.js +21 -0
  85. package/dist/components/InputGroup.cjs +270 -0
  86. package/dist/components/InputGroup.js +60 -0
  87. package/dist/components/Label.cjs +223 -0
  88. package/dist/components/Label.js +8 -0
  89. package/dist/components/Link.cjs +262 -0
  90. package/dist/components/Link.js +8 -0
  91. package/dist/components/List.cjs +37 -0
  92. package/dist/components/List.js +14 -0
  93. package/dist/components/LiveChatComponent.cjs +63 -0
  94. package/dist/components/LiveChatComponent.js +40 -0
  95. package/dist/components/LogoAgilityTopBar.cjs +115 -0
  96. package/dist/components/LogoAgilityTopBar.js +92 -0
  97. package/dist/components/LogoDMSiTopBar.cjs +79 -0
  98. package/dist/components/LogoDMSiTopBar.js +7 -0
  99. package/dist/components/LogoMillworkTopBar.cjs +221 -0
  100. package/dist/components/LogoMillworkTopBar.js +198 -0
  101. package/dist/components/MainBar.cjs +211 -0
  102. package/dist/components/MainBar.js +65 -0
  103. package/dist/components/Menu.cjs +437 -0
  104. package/dist/components/Menu.js +11 -0
  105. package/dist/components/MenuOption.cjs +483 -0
  106. package/dist/components/MenuOption.js +13 -0
  107. package/dist/components/MobileDataGrid.cjs +658 -0
  108. package/dist/components/MobileDataGrid.js +125 -0
  109. package/dist/components/Modal.cjs +783 -0
  110. package/dist/components/Modal.js +245 -0
  111. package/dist/components/ModalButtons.cjs +385 -0
  112. package/dist/components/ModalButtons.js +10 -0
  113. package/dist/components/ModalContent.cjs +57 -0
  114. package/dist/components/ModalContent.js +7 -0
  115. package/dist/components/ModalHeader.cjs +426 -0
  116. package/dist/components/ModalHeader.js +11 -0
  117. package/dist/components/ModalScrim.cjs +64 -0
  118. package/dist/components/ModalScrim.js +7 -0
  119. package/dist/components/NavigationTab.cjs +431 -0
  120. package/dist/components/NavigationTab.js +10 -0
  121. package/dist/components/NavigationTabs.cjs +477 -0
  122. package/dist/components/NavigationTabs.js +56 -0
  123. package/dist/components/Notification.cjs +640 -0
  124. package/dist/components/Notification.js +117 -0
  125. package/dist/components/OptionPill.cjs +478 -0
  126. package/dist/components/OptionPill.js +11 -0
  127. package/dist/components/Paragraph.cjs +231 -0
  128. package/dist/components/Paragraph.js +8 -0
  129. package/dist/components/Password.cjs +700 -0
  130. package/dist/components/Password.js +53 -0
  131. package/dist/components/ProjectBar.cjs +242 -0
  132. package/dist/components/ProjectBar.js +63 -0
  133. package/dist/components/Radio.cjs +349 -0
  134. package/dist/components/Radio.js +131 -0
  135. package/dist/components/Search.cjs +767 -0
  136. package/dist/components/Search.js +12 -0
  137. package/dist/components/Select.cjs +758 -0
  138. package/dist/components/Select.js +12 -0
  139. package/dist/components/SideMenu.cjs +54 -0
  140. package/dist/components/SideMenu.js +21 -0
  141. package/dist/components/SideMenuGroup.cjs +422 -0
  142. package/dist/components/SideMenuGroup.js +83 -0
  143. package/dist/components/SideMenuItem.cjs +388 -0
  144. package/dist/components/SideMenuItem.js +70 -0
  145. package/dist/components/Stack.cjs +138 -0
  146. package/dist/components/Stack.js +7 -0
  147. package/dist/components/StatusPill.cjs +265 -0
  148. package/dist/components/StatusPill.js +52 -0
  149. package/dist/components/Stepper.cjs +885 -0
  150. package/dist/components/Stepper.js +105 -0
  151. package/dist/components/Subheader.cjs +226 -0
  152. package/dist/components/Subheader.js +8 -0
  153. package/dist/components/Surface.cjs +98 -0
  154. package/dist/components/Surface.js +40 -0
  155. package/dist/components/Swatch.cjs +1728 -0
  156. package/dist/components/Swatch.js +1319 -0
  157. package/dist/components/Textarea.cjs +269 -0
  158. package/dist/components/Textarea.js +96 -0
  159. package/dist/components/Theme.cjs +36 -0
  160. package/dist/components/Theme.js +7 -0
  161. package/dist/components/Time.cjs +1118 -0
  162. package/dist/components/Time.js +353 -0
  163. package/dist/components/Toast.cjs +644 -0
  164. package/dist/components/Toast.js +218 -0
  165. package/dist/components/Tooltip.cjs +273 -0
  166. package/dist/components/Tooltip.js +9 -0
  167. package/dist/components/TopBar.cjs +352 -0
  168. package/dist/components/TopBar.js +132 -0
  169. package/dist/components/useInfiniteScroll.cjs +57 -0
  170. package/dist/components/useInfiniteScroll.js +8 -0
  171. package/dist/components/useMatchesMedia.cjs +53 -0
  172. package/dist/components/useMatchesMedia.js +9 -0
  173. package/dist/components/useMenuSystem.cjs +358 -0
  174. package/dist/components/useMenuSystem.js +11 -0
  175. package/dist/components/useMounted.cjs +39 -0
  176. package/dist/components/useMounted.js +8 -0
  177. package/dist/fonts.css +21 -0
  178. package/dist/icons-light[FILL]-PPZXOLWS.woff2 +0 -0
  179. package/dist/icons-normal[FILL]-PPZXOLWS.woff2 +0 -0
  180. package/dist/index.css +4401 -0
  181. package/dist/open-sans-55T6A4JE.woff2 +0 -0
  182. package/dist/types.cjs +18 -0
  183. package/dist/types.js +0 -0
  184. package/package.json +66 -0
  185. package/src/brand.css +125 -0
  186. package/src/classNames.ts +144 -0
  187. package/src/components/Breadcrumbs.tsx +116 -0
  188. package/src/components/Button.tsx +210 -0
  189. package/src/components/CalendarRange.tsx +429 -0
  190. package/src/components/Caption.tsx +101 -0
  191. package/src/components/Checkbox.tsx +196 -0
  192. package/src/components/ContentTab.tsx +66 -0
  193. package/src/components/ContentTabs.tsx +103 -0
  194. package/src/components/DMSiLogo.tsx +32 -0
  195. package/src/components/DataGrid.tsx +948 -0
  196. package/src/components/DataGridCell.tsx +384 -0
  197. package/src/components/DataTable.tsx +835 -0
  198. package/src/components/DateInput.tsx +188 -0
  199. package/src/components/DateRangeInput.tsx +179 -0
  200. package/src/components/DebugJson.tsx +24 -0
  201. package/src/components/Display.tsx +60 -0
  202. package/src/components/EditingContext.tsx +40 -0
  203. package/src/components/FilterGroup.tsx +234 -0
  204. package/src/components/FullViewportBox.tsx +11 -0
  205. package/src/components/Grid.tsx +75 -0
  206. package/src/components/GridContainer.tsx +124 -0
  207. package/src/components/Heading.tsx +66 -0
  208. package/src/components/HorizontalDivider.tsx +3 -0
  209. package/src/components/Icon.tsx +36 -0
  210. package/src/components/Input.tsx +511 -0
  211. package/src/components/InputGroup.tsx +51 -0
  212. package/src/components/Label.tsx +40 -0
  213. package/src/components/Link.tsx +106 -0
  214. package/src/components/List.tsx +10 -0
  215. package/src/components/LiveChatComponent.tsx +56 -0
  216. package/src/components/LogoAgilityTopBar.tsx +53 -0
  217. package/src/components/LogoDMSiTopBar.tsx +32 -0
  218. package/src/components/LogoMillworkTopBar.tsx +118 -0
  219. package/src/components/MainBar.tsx +83 -0
  220. package/src/components/Menu.tsx +286 -0
  221. package/src/components/MenuOption.tsx +275 -0
  222. package/src/components/MobileDataGrid.tsx +135 -0
  223. package/src/components/Modal.tsx +271 -0
  224. package/src/components/ModalButtons.tsx +44 -0
  225. package/src/components/ModalContent.tsx +23 -0
  226. package/src/components/ModalHeader.tsx +41 -0
  227. package/src/components/ModalScrim.tsx +35 -0
  228. package/src/components/NavigationTab.tsx +89 -0
  229. package/src/components/NavigationTabs.tsx +63 -0
  230. package/src/components/Notification.tsx +120 -0
  231. package/src/components/OptionPill.tsx +114 -0
  232. package/src/components/Paragraph.tsx +49 -0
  233. package/src/components/Password.tsx +46 -0
  234. package/src/components/ProjectBar.tsx +76 -0
  235. package/src/components/Radio.tsx +140 -0
  236. package/src/components/Search.tsx +129 -0
  237. package/src/components/Select.tsx +104 -0
  238. package/src/components/SideMenu.tsx +21 -0
  239. package/src/components/SideMenuGroup.tsx +81 -0
  240. package/src/components/SideMenuItem.tsx +90 -0
  241. package/src/components/Stack.tsx +179 -0
  242. package/src/components/StatusPill.tsx +51 -0
  243. package/src/components/Stepper.tsx +91 -0
  244. package/src/components/Subheader.tsx +44 -0
  245. package/src/components/Surface.tsx +34 -0
  246. package/src/components/Swatch.tsx +1066 -0
  247. package/src/components/Textarea.tsx +101 -0
  248. package/src/components/Theme.tsx +13 -0
  249. package/src/components/Time.tsx +438 -0
  250. package/src/components/Toast.tsx +244 -0
  251. package/src/components/Tooltip.tsx +137 -0
  252. package/src/components/TopBar.tsx +124 -0
  253. package/src/components/useInfiniteScroll.tsx +40 -0
  254. package/src/components/useMatchesMedia.tsx +28 -0
  255. package/src/components/useMenuSystem.tsx +367 -0
  256. package/src/components/useMounted.tsx +14 -0
  257. package/src/darkmode.css +140 -0
  258. package/src/fonts.css +23 -0
  259. package/src/index.css +509 -0
  260. package/src/index.tsx +2 -0
  261. package/src/types.ts +149 -0
  262. package/src/utils/formatting.tsx +81 -0
  263. package/src/utils.ts +23 -0
@@ -0,0 +1,835 @@
1
+ "use client";
2
+ import React, {
3
+ createContext,
4
+ CSSProperties,
5
+ PropsWithChildren,
6
+ ReactNode,
7
+ useContext,
8
+ useEffect,
9
+ useState,
10
+ } from "react";
11
+
12
+ import {
13
+ Cell,
14
+ Column,
15
+ ColumnDef,
16
+ ColumnFiltersState,
17
+ flexRender,
18
+ getCoreRowModel,
19
+ getFilteredRowModel,
20
+ getPaginationRowModel,
21
+ getSortedRowModel,
22
+ Header,
23
+ PaginationState,
24
+ // RowData,
25
+ SortingState,
26
+ useReactTable,
27
+ } from "@tanstack/react-table";
28
+ import clsx from "clsx";
29
+
30
+ import {
31
+ closestCenter,
32
+ DndContext,
33
+ type DragEndEvent,
34
+ KeyboardSensor,
35
+ MouseSensor,
36
+ TouchSensor,
37
+ useSensor,
38
+ useSensors,
39
+ } from "@dnd-kit/core";
40
+ import { restrictToHorizontalAxis } from "@dnd-kit/modifiers";
41
+ import {
42
+ arrayMove,
43
+ horizontalListSortingStrategy,
44
+ SortableContext,
45
+ } from "@dnd-kit/sortable";
46
+
47
+ import { useSortable } from "@dnd-kit/sortable";
48
+ import { CSS } from "@dnd-kit/utilities";
49
+ import { Switch } from "@headlessui/react";
50
+
51
+ export interface DataTableProps {
52
+ data: OrderRow[];
53
+ }
54
+
55
+ export type OrderRow = {
56
+ orderId: string;
57
+ poId: string;
58
+ jobId: string;
59
+ reference: string;
60
+ reference1: string;
61
+ reference12: string;
62
+ reference13: string;
63
+ reference14: string;
64
+ reference15: string;
65
+ reference16: string;
66
+ reference17: string;
67
+ reference18: string;
68
+ reference19: string;
69
+ reference10: string;
70
+ reference11: string;
71
+ shipToStatus: string;
72
+ orderedDate: string;
73
+ };
74
+
75
+ const columns: ColumnDef<OrderRow>[] = [
76
+ {
77
+ header: "Order ID",
78
+ accessorKey: "orderId",
79
+ id: "orderId",
80
+ meta: {
81
+ sticky: true,
82
+ },
83
+ },
84
+ {
85
+ header: "Actions",
86
+ id: "actions",
87
+ cell: () => {
88
+ const items = [
89
+ {
90
+ label: "Release",
91
+ icon: <i className="w-3 h-3" />,
92
+ },
93
+ { label: "XML", icon: <i className="w-3 h-3" /> },
94
+ { label: "Copy", icon: <i className="w-3 h-3" /> },
95
+ { label: "Quote", icon: <i className="w-3 h-3" /> },
96
+ { label: "Retail", icon: <i className="w-3 h-3" /> },
97
+ ];
98
+ return (
99
+ <div className="flex flex-row gap-3">
100
+ {items.map((item, index) => (
101
+ <div
102
+ className="flex flex-col items-center justify-center gap-1"
103
+ key={index}
104
+ >
105
+ {item.icon}
106
+ <span className="text-[0.6rem] block text-neutral-500 font-semibold">
107
+ {item.label}
108
+ </span>
109
+ </div>
110
+ ))}
111
+ </div>
112
+ );
113
+ },
114
+ },
115
+ {
116
+ header: "PO ID",
117
+ accessorKey: "poId",
118
+ id: "poId",
119
+ },
120
+ {
121
+ header: "Job ID",
122
+ accessorKey: "jobId",
123
+ id: "jobId",
124
+ },
125
+ {
126
+ header: "Reference",
127
+ accessorKey: "reference",
128
+ id: "reference",
129
+ meta: {
130
+ className: "hidden md:table-cell",
131
+ },
132
+ },
133
+ {
134
+ header: "Status",
135
+ accessorKey: "shipToStatus",
136
+ id: "shipToStatus",
137
+ meta: {
138
+ filterVariant: "select",
139
+ },
140
+ },
141
+ {
142
+ header: "Ordered date",
143
+ accessorKey: "orderedDate",
144
+ id: "orderedDate",
145
+ },
146
+ {
147
+ header: "Reference 1",
148
+ accessorKey: "reference1",
149
+ id: "reference1",
150
+ meta: { className: "hidden md:table-cell" },
151
+ },
152
+ {
153
+ header: "Reference 12",
154
+ accessorKey: "reference12",
155
+ id: "reference12",
156
+ meta: { className: "hidden md:table-cell" },
157
+ },
158
+ {
159
+ header: "Reference 13",
160
+ accessorKey: "reference13",
161
+ id: "reference13",
162
+ meta: { className: "hidden md:table-cell" },
163
+ },
164
+ {
165
+ header: "Reference 14",
166
+ accessorKey: "reference14",
167
+ id: "reference14",
168
+ meta: { className: "hidden md:table-cell" },
169
+ },
170
+ {
171
+ header: "Reference 15",
172
+ accessorKey: "reference15",
173
+ id: "reference15",
174
+ meta: { className: "hidden md:table-cell" },
175
+ },
176
+ {
177
+ header: "Reference 16",
178
+ accessorKey: "reference16",
179
+ id: "reference16",
180
+ meta: { className: "hidden md:table-cell" },
181
+ },
182
+ {
183
+ header: "Reference 17",
184
+ accessorKey: "reference17",
185
+ id: "reference17",
186
+ meta: { className: "hidden md:table-cell" },
187
+ },
188
+ {
189
+ header: "Reference 18",
190
+ accessorKey: "reference18",
191
+ id: "reference18",
192
+ meta: { className: "hidden md:table-cell" },
193
+ },
194
+ {
195
+ header: "Reference 19",
196
+ accessorKey: "reference19",
197
+ id: "reference19",
198
+ meta: { className: "hidden md:table-cell" },
199
+ },
200
+ {
201
+ header: "Reference 10",
202
+ accessorKey: "reference10",
203
+ id: "reference10",
204
+ meta: { className: "hidden md:table-cell" },
205
+ },
206
+ {
207
+ header: "Reference 11",
208
+ accessorKey: "reference11",
209
+ id: "reference11",
210
+ meta: { className: "hidden md:table-cell" },
211
+ },
212
+ ];
213
+
214
+ const EditingContext = createContext<{
215
+ data: OrderRow[];
216
+ setValue: (row: number, key: string, value: string) => void;
217
+ }>({
218
+ data: [],
219
+ setValue: (row: number, key: string, value: string) => {
220
+ console.log(row, key, value);
221
+ },
222
+ });
223
+
224
+ type EditingProviderProps = PropsWithChildren<{ data: OrderRow[] }>;
225
+
226
+ export const EditingProvider = ({ data, children }: EditingProviderProps) => {
227
+ const [actual, setData] = useState(data);
228
+ useEffect(() => console.log("data changed"), [actual]);
229
+ const context = {
230
+ data: actual,
231
+ setValue: (row: number, key: string, value: string) => {
232
+ setData((prev) => {
233
+ const newData = [...prev];
234
+ newData[row] = {
235
+ ...newData[row],
236
+ [key]: value,
237
+ };
238
+ return newData;
239
+ });
240
+ },
241
+ };
242
+ return <EditingContext value={context}>{children}</EditingContext>;
243
+ };
244
+ export const DataTable = ({ data }: DataTableProps) => {
245
+ return (
246
+ <EditingProvider data={data}>
247
+ <DataTableInternals />
248
+ </EditingProvider>
249
+ );
250
+ };
251
+
252
+ const DraggableTableHeader = ({
253
+ header,
254
+ }: {
255
+ header: Header<OrderRow, unknown>;
256
+ }) => {
257
+ const { attributes, isDragging, listeners, setNodeRef, transform } =
258
+ useSortable({
259
+ id: header.column.id,
260
+ });
261
+
262
+ const style: CSSProperties = {
263
+ opacity: isDragging ? 0.8 : 1,
264
+ position: "relative",
265
+ transform: CSS.Translate.toString(transform),
266
+ transition: "width transform 0.2s ease-in-out",
267
+ whiteSpace: "nowrap",
268
+ width: header.column.getSize(),
269
+ zIndex: isDragging ? 1 : 0,
270
+ };
271
+
272
+ return (
273
+ <th
274
+ colSpan={header.colSpan}
275
+ ref={setNodeRef}
276
+ style={style}
277
+ className={clsx(
278
+ header.column.columnDef.meta?.className,
279
+ "px-3 py-3.5 text-left text-sm font-semibold text-dmsi-white bg-dmsi-red ",
280
+ {
281
+ "sticky left-0": header.column.columnDef.meta?.sticky ?? false,
282
+ },
283
+ )}
284
+ >
285
+ {header.isPlaceholder ? null : (
286
+ <div className="flex space-x-1 justify-start items-center">
287
+ <button
288
+ className="cursor-grab shrink-0"
289
+ {...attributes}
290
+ {...listeners}
291
+ >
292
+ <i className="w-3 h-3" />
293
+ </button>
294
+
295
+ <div
296
+ className={clsx(
297
+ "grow",
298
+ header.column.getCanSort() ? "cursor-pointer select-none" : "",
299
+ "flex flex-col gap-1 justify-between items-start",
300
+ )}
301
+ title={
302
+ header.column.getCanSort()
303
+ ? header.column.getNextSortingOrder() === "asc"
304
+ ? "Sort ascending"
305
+ : header.column.getNextSortingOrder() === "desc"
306
+ ? "Sort descending"
307
+ : "Clear sort"
308
+ : undefined
309
+ }
310
+ >
311
+ <div>
312
+ {flexRender(header.column.columnDef.header, header.getContext())}
313
+ </div>
314
+ <div>
315
+ {header.column.getCanFilter() ? (
316
+ <Filter column={header.column} />
317
+ ) : (
318
+ <div className="invisible">
319
+ <Filter column={header.column} />
320
+ </div>
321
+ )}
322
+ </div>
323
+ </div>
324
+ <div
325
+ className="shrink-0 cursor-pointer"
326
+ onClick={header.column.getToggleSortingHandler()}
327
+ >
328
+ {{
329
+ asc: <i className="w-3 h-3" />,
330
+ desc: <i className="w-3 h-3" />,
331
+ }[header.column.getIsSorted() as string] ?? (
332
+ <i className="w-3 h-3" />
333
+ )}
334
+ </div>
335
+ </div>
336
+ )}
337
+ </th>
338
+ );
339
+ };
340
+
341
+ const DragAlongCell = ({
342
+ cell,
343
+ setValue,
344
+ }: {
345
+ cell: Cell<OrderRow, unknown>;
346
+ setValue: (row: number, key: string, value: string) => void;
347
+ }) => {
348
+ const { isDragging, setNodeRef, transform } = useSortable({
349
+ id: cell.column.id,
350
+ });
351
+
352
+ const style: CSSProperties = {
353
+ opacity: isDragging ? 0.8 : 1,
354
+ position: "relative",
355
+ transform: CSS.Translate.toString(transform),
356
+ transition: "width transform 0.2s ease-in-out",
357
+ width: cell.column.getSize(),
358
+ zIndex: isDragging ? 1 : 0,
359
+ };
360
+
361
+ return (
362
+ <EditCell
363
+ ref={setNodeRef}
364
+ style={style}
365
+ cell={cell}
366
+ className={clsx(
367
+ cell.column.columnDef.meta?.className ?? "",
368
+ "text-sm whitespace-nowrap text-gray-900 bg-neutral-100",
369
+ {
370
+ "sticky left-0": cell.column.columnDef.meta?.sticky ?? false,
371
+ },
372
+ )}
373
+ setValue={setValue}
374
+ />
375
+ );
376
+ };
377
+
378
+ const DataTableInternals = () => {
379
+ // use state client bullshit
380
+
381
+ const { data, setValue } = useContext(EditingContext);
382
+ const [columnOrder, setColumnOrder] = React.useState<string[]>(() =>
383
+ columns.map((c) => c.id!),
384
+ );
385
+ const [pagination, setPagination] = useState<PaginationState>({
386
+ pageIndex: 0,
387
+ pageSize: 10,
388
+ });
389
+ const [columnVisibility, setColumnVisibility] = useState(
390
+ columns.reduce(
391
+ (acc, column) => {
392
+ if ("accessorKey" in column) {
393
+ acc[column.accessorKey as string] = true;
394
+ }
395
+ return acc;
396
+ },
397
+ {} as Record<string, boolean>,
398
+ ),
399
+ );
400
+ const [sorting, setSorting] = useState<SortingState>([]);
401
+ const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]); // can set initial column filter state here
402
+ const table = useReactTable<OrderRow>({
403
+ columns,
404
+ data,
405
+ debugAll: true,
406
+ getCoreRowModel: getCoreRowModel(),
407
+ getFilteredRowModel: getFilteredRowModel(),
408
+ getSortedRowModel: getSortedRowModel(),
409
+ getPaginationRowModel: getPaginationRowModel(),
410
+ onSortingChange: setSorting,
411
+ onColumnFiltersChange: setColumnFilters,
412
+ onPaginationChange: setPagination,
413
+ onColumnVisibilityChange: setColumnVisibility,
414
+ onColumnOrderChange: setColumnOrder,
415
+ state: {
416
+ sorting,
417
+ columnFilters,
418
+ pagination,
419
+ columnVisibility,
420
+ columnOrder,
421
+ },
422
+ });
423
+
424
+ function handleDragEnd(event: DragEndEvent) {
425
+ const { active, over } = event;
426
+ if (active && over && active.id !== over.id) {
427
+ setColumnOrder((columnOrder) => {
428
+ const oldIndex = columnOrder.indexOf(active.id as string);
429
+ const newIndex = columnOrder.indexOf(over.id as string);
430
+ return arrayMove(columnOrder, oldIndex, newIndex);
431
+ });
432
+ }
433
+ }
434
+
435
+ const sensors = useSensors(
436
+ useSensor(MouseSensor, {}),
437
+ useSensor(TouchSensor, {}),
438
+ useSensor(KeyboardSensor, {}),
439
+ );
440
+
441
+ return (
442
+ <DndContext
443
+ collisionDetection={closestCenter}
444
+ modifiers={[restrictToHorizontalAxis]}
445
+ onDragEnd={handleDragEnd}
446
+ sensors={sensors}
447
+ >
448
+ <div>
449
+ <div className="border border-gray-300 rounded p-3 m-4 max-w-xl min-w-0">
450
+ <p className="mb-3 font-semibold">Show/Hide Columns</p>
451
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-2">
452
+ {table.getAllColumns().map((column) => (
453
+ <label
454
+ className="cursor-pointer flex flex-row items-center space-x-1"
455
+ key={column.id}
456
+ >
457
+ <Toggle
458
+ enabled={column.getIsVisible()}
459
+ onToggle={(checked) =>
460
+ column.getToggleVisibilityHandler()({
461
+ target: { checked },
462
+ })
463
+ }
464
+ />
465
+
466
+ <span className="block">
467
+ {column.columnDef.header as ReactNode}
468
+ </span>
469
+ </label>
470
+ ))}
471
+ </div>
472
+ </div>
473
+
474
+ <div className="overflow-x-scroll scrollbar-thin">
475
+ <table className="min-w-full divide-x divide-neutral-500">
476
+ <thead>
477
+ {table.getHeaderGroups().map((headerGroup) => (
478
+ <tr key={headerGroup.id}>
479
+ <SortableContext
480
+ items={columnOrder}
481
+ strategy={horizontalListSortingStrategy}
482
+ >
483
+ {headerGroup.headers.map((header) => (
484
+ <DraggableTableHeader key={header.id} header={header} />
485
+ ))}
486
+ </SortableContext>
487
+ </tr>
488
+ ))}
489
+ </thead>
490
+ <tbody>
491
+ {table.getRowModel().rows.map((row) => (
492
+ <tr
493
+ key={row.id}
494
+ className="bg-neutral-100 divide-y divide-neutral-200"
495
+ >
496
+ {row.getVisibleCells().map((cell) => (
497
+ <SortableContext
498
+ key={cell.id}
499
+ items={columnOrder}
500
+ strategy={horizontalListSortingStrategy}
501
+ >
502
+ <DragAlongCell
503
+ key={cell.id}
504
+ cell={cell}
505
+ setValue={setValue}
506
+ />
507
+ </SortableContext>
508
+ ))}
509
+ </tr>
510
+ ))}
511
+ </tbody>
512
+ </table>
513
+ </div>
514
+ <div className="flex flex-col gap-6 md:flex-row items-center md:gap-2 w-full justify-between p-2">
515
+ <div className="flex flex-row items-center">
516
+ <button
517
+ className={clsx(
518
+ "group flex items-center justify-center h-8 w-8 border border-gray-500/50 text-gray-700 rounded p-1 hover:bg-dmsi-blue hover:text-white transition-colors cursor-pointer border-r-0 rounded-r-none",
519
+ {
520
+ "pointer-events-none": !table.getCanPreviousPage(),
521
+ },
522
+ )}
523
+ onClick={() => table.setPageIndex(0)}
524
+ disabled={!table.getCanPreviousPage()}
525
+ >
526
+ <i className="w-4 h-4 group-disabled:stroke-gray-400" />
527
+ </button>
528
+ <button
529
+ className={clsx(
530
+ "-mr-px group flex items-center justify-center h-8 w-8 border border-gray-500/50 text-gray-700 p-1 hover:bg-dmsi-blue hover:text-white transition-colors cursor-pointer",
531
+ {
532
+ "pointer-events-none": !table.getCanPreviousPage(),
533
+ },
534
+ )}
535
+ onClick={() => table.previousPage()}
536
+ disabled={!table.getCanPreviousPage()}
537
+ >
538
+ <i className="w-4 h-4 group-disabled:stroke-gray-400" />
539
+ </button>
540
+ {Array.from({ length: Math.min(5, table.getPageCount()) }).map(
541
+ (_, i) => {
542
+ const current = table.getState().pagination.pageIndex;
543
+ const index = current - 2 + i;
544
+ const active = index === current;
545
+ if (index < 0) return;
546
+ if (index > table.getPageCount() - 1) return;
547
+ return (
548
+ <button
549
+ key={i}
550
+ className={clsx(
551
+ "group h-8 w-8 border-y border-gray-500/50 text-gray-700 p-1 hover:bg-dmsi-blue hover:text-white transition-colors cursor-pointer flex items-center justify-center",
552
+ {
553
+ "bg-neutral-200 border-x": active,
554
+ "border-r-0": !active,
555
+ },
556
+ )}
557
+ onClick={() => table.setPageIndex(index)}
558
+ >
559
+ <span className={clsx({})}>{index + 1}</span>
560
+ </button>
561
+ );
562
+ },
563
+ )}
564
+ <button
565
+ className={clsx(
566
+ "-ml-px group flex items-center justify-center h-8 w-8 border border-gray-500/50 text-gray-700 p-1 hover:bg-dmsi-blue hover:text-white transition-colors cursor-pointer border-r-0 group",
567
+ {
568
+ "pointer-events-none": !table.getCanNextPage(),
569
+ },
570
+ )}
571
+ onClick={() => table.nextPage()}
572
+ disabled={!table.getCanNextPage()}
573
+ >
574
+ <i className="w-4 h-4 group-disabled:stroke-gray-400 " />
575
+ </button>
576
+ <button
577
+ className={clsx(
578
+ "group flex items-center justify-center h-8 w-8 border border-gray-500/50 text-gray-700 rounded rounded-l-none p-1 hover:bg-dmsi-blue hover:text-white transition-colors cursor-pointer",
579
+ {
580
+ "pointer-events-none": !table.getCanNextPage(),
581
+ },
582
+ )}
583
+ onClick={() => table.setPageIndex(table.getPageCount() - 1)}
584
+ disabled={!table.getCanNextPage()}
585
+ >
586
+ <i className="w-4 h-4 group-disabled:stroke-gray-400" />
587
+ </button>
588
+ </div>
589
+ <div className="flex flex-row items-center gap-6">
590
+ <span className="flex items-center gap-1">
591
+ <div>Page</div>
592
+ <strong>
593
+ {table.getState().pagination.pageIndex + 1} of{" "}
594
+ {table.getPageCount()}
595
+ </strong>
596
+ </span>
597
+ <span className="flex items-center gap-2">
598
+ Page:
599
+ <input
600
+ type="number"
601
+ min="1"
602
+ max={table.getPageCount()}
603
+ defaultValue={table.getState().pagination.pageIndex + 1}
604
+ onChange={(e) => {
605
+ const page = e.target.value ? Number(e.target.value) - 1 : 0;
606
+ table.setPageIndex(page);
607
+ }}
608
+ className="border border-gray-500 px-2 py-1 rounded w-16"
609
+ />
610
+ </span>
611
+ </div>
612
+ <select
613
+ className="border border-gray-500 px-2 py-1 rounded"
614
+ value={table.getState().pagination.pageSize}
615
+ onChange={(e) => {
616
+ table.setPageSize(Number(e.target.value));
617
+ }}
618
+ >
619
+ {[10, 20, 30, 40, 50].map((pageSize) => (
620
+ <option key={pageSize} value={pageSize}>
621
+ Show {pageSize}
622
+ </option>
623
+ ))}
624
+ </select>
625
+ </div>
626
+ </div>
627
+ </DndContext>
628
+ );
629
+ };
630
+
631
+ function EditCell({
632
+ className,
633
+ cell,
634
+ setValue,
635
+ style,
636
+ ref,
637
+ }: {
638
+ className?: string;
639
+ cell: Cell<OrderRow, unknown>;
640
+ setValue: (row: number, key: string, value: string) => void;
641
+ style: CSSProperties;
642
+ ref: (node: HTMLElement | null) => void;
643
+ }) {
644
+ const [editing, setEditing] = useState(false);
645
+ const value = cell.getValue();
646
+ const isString = typeof value === "string";
647
+ const [editedValue, setEditedValue] = useState<string>(isString ? value : "");
648
+ const onStartEdit = () => {
649
+ if (isString) {
650
+ setEditing(true);
651
+ }
652
+ };
653
+ const onEditValue = (e: React.ChangeEvent<HTMLInputElement>) => {
654
+ setEditedValue(e.target.value);
655
+ };
656
+ const onStopEdit = () => {
657
+ setValue(cell.row.index, cell.column.id, editedValue);
658
+ setEditing(false);
659
+ };
660
+ const onKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
661
+ if (e.key === "Enter") {
662
+ onStopEdit();
663
+ }
664
+ };
665
+
666
+ return (
667
+ <td
668
+ key={cell.id}
669
+ className={clsx(
670
+ className,
671
+ cell.column.columnDef.meta?.className ?? "",
672
+ "px-2 py-3 text-sm whitespace-nowrap text-gray-500",
673
+ )}
674
+ style={style}
675
+ ref={ref}
676
+ >
677
+ {isString && editing && (
678
+ <div className="flex flex-row gap-1">
679
+ <input
680
+ type="text"
681
+ value={editedValue}
682
+ onChange={onEditValue}
683
+ onKeyUp={onKeyUp}
684
+ onBlur={onStopEdit}
685
+ className="border px-2 py-0.5 rounded inline min-w-0 shrink border-neutral-400 focus:outline-neutral-300 bg-white"
686
+ />
687
+ <button
688
+ onClick={onStopEdit}
689
+ className="border cursor-pointer px-2 py-0.5 rounded flex items-center justify-center w-12 border-dmsi-blue text-dmsi-blue bg-white"
690
+ >
691
+ Save
692
+ </button>
693
+ </div>
694
+ )}
695
+ {!editing && (
696
+ <div
697
+ onClick={onStartEdit}
698
+ className="px-2 py-1 flex flex-row items-center"
699
+ >
700
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
701
+ <div className="w-16"></div>
702
+ </div>
703
+ )}
704
+ </td>
705
+ );
706
+ }
707
+
708
+ function Filter({ column }: { column: Column<OrderRow> }) {
709
+ const columnFilterValue = column.getFilterValue();
710
+
711
+ const { filterVariant } = column.columnDef.meta ?? {};
712
+
713
+ return filterVariant === "range" ? (
714
+ <div>
715
+ <div className="flex space-x-2">
716
+ {/* See faceted column filters example for min max values functionality */}
717
+ <input
718
+ className="block w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-neutral-400 sm:text-sm/6"
719
+ type="number"
720
+ value={(columnFilterValue as [number, number])?.[0] ?? ""}
721
+ onChange={(e) =>
722
+ column.setFilterValue((old: [number, number]) => [
723
+ e.target.value,
724
+ old?.[1],
725
+ ])
726
+ }
727
+ autoComplete="off"
728
+ placeholder={`Min`}
729
+ />
730
+ <input
731
+ className="block w-full rounded-md bg-white px-3 py-0.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-neutral-400 sm:text-sm/6"
732
+ type="number"
733
+ value={(columnFilterValue as [number, number])?.[1] ?? ""}
734
+ onChange={(e) =>
735
+ column.setFilterValue((old: [number, number]) => [
736
+ old?.[0],
737
+ e.target.value,
738
+ ])
739
+ }
740
+ autoComplete="off"
741
+ placeholder={`Max`}
742
+ />
743
+ </div>
744
+ <div className="h-1" />
745
+ </div>
746
+ ) : filterVariant === "select" ? (
747
+ <select
748
+ className="block min-w-36 w-full rounded-md bg-white px-2 py-2 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-neutral-400 sm:text-sm/6"
749
+ onChange={(e) => column.setFilterValue(e.target.value)}
750
+ value={columnFilterValue?.toString()}
751
+ >
752
+ {/* See faceted column filters example for dynamic select options */}
753
+ <option value="">Status: All</option>
754
+ <option value="cancelled">Status: Cancelled</option>
755
+ <option value="pending">Status: Pending</option>
756
+ <option value="shipped">Status: Shipped</option>
757
+ </select>
758
+ ) : (
759
+ <input
760
+ className="block min-w-36 w-full rounded-md bg-white px-3 py-1.5 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-neutral-400 sm:text-sm/6"
761
+ onChange={(e) => column.setFilterValue(e.target.value)}
762
+ placeholder={column.columnDef.header?.toString() ?? "..."}
763
+ type="text"
764
+ autoComplete="off"
765
+ value={(columnFilterValue ?? "") as string}
766
+ />
767
+ // See faceted column filters example for datalist search suggestions
768
+ );
769
+ }
770
+
771
+ // // A typical debounced input react component
772
+ // // This debounce is not working correctly?
773
+ // function DebouncedInput({
774
+ // value: initialValue,
775
+ // onChange,
776
+ // debounce = 500,
777
+ // ...props
778
+ // }: {
779
+ // value: string | number;
780
+ // onChange: (value: string | number) => void;
781
+ // debounce?: number;
782
+ // } & Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange">) {
783
+ // const [value, setValue] = React.useState(initialValue);
784
+
785
+ // React.useEffect(() => {
786
+ // if (value !== initialValue) {
787
+ // setValue(initialValue);
788
+ // }
789
+ // }, [initialValue, setValue, value]);
790
+
791
+ // React.useEffect(() => {
792
+ // if (value === initialValue) {
793
+ // return;
794
+ // }
795
+
796
+ // const timeout = setTimeout(() => {
797
+ // onChange(value);
798
+ // }, debounce);
799
+
800
+ // return () => clearTimeout(timeout);
801
+ // }, [value, debounce, onChange, initialValue]);
802
+
803
+ // return (
804
+ // <input
805
+ // {...props}
806
+ // value={value}
807
+ // onChange={(e) => setValue(e.target.value)}
808
+ // />
809
+ // );
810
+ // }
811
+
812
+ Switch.displayName = "Switch";
813
+
814
+ export default function Toggle({
815
+ enabled,
816
+ onToggle,
817
+ }: {
818
+ enabled: boolean;
819
+ onToggle: (enabled: boolean) => void;
820
+ }) {
821
+ return (
822
+ <Switch
823
+ checked={enabled}
824
+ onChange={onToggle}
825
+ className="group relative flex h-4 w-7 cursor-pointer rounded-full p-0.5 transition-colors duration-200 ease-in-out focus:outline-none data-[focus]:outline-1 data-[focus]:outline-white bg-neutral-900/10 data-[checked]:bg-dmsi-blue"
826
+ >
827
+ <span
828
+ aria-hidden="true"
829
+ className="pointer-events-none inline-block size-3 translate-x-0 rounded-full bg-white ring-0 shadow-lg transition duration-200 ease-in-out group-data-[checked]:translate-x-3 group-data-[checked]:shadow-lg"
830
+ />
831
+ </Switch>
832
+ );
833
+ }
834
+
835
+ Toggle.displayName = "Toggle";