@mdaushi/kinetics-react 0.1.0-a

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/index.cjs ADDED
@@ -0,0 +1,788 @@
1
+ 'use strict';
2
+
3
+ var react = require('@inertiajs/react');
4
+ var reactTable = require('@tanstack/react-table');
5
+ var React = require('react');
6
+ var useDebounce = require('use-debounce');
7
+ var kineticsCore = require('@mdaushi/kinetics-core');
8
+ var clsx = require('clsx');
9
+ var tailwindMerge = require('tailwind-merge');
10
+ var button = require('@base-ui/react/button');
11
+ var classVarianceAuthority = require('class-variance-authority');
12
+ var jsxRuntime = require('react/jsx-runtime');
13
+ var menu = require('@base-ui/react/menu');
14
+ var lucideReact = require('lucide-react');
15
+ var dynamic = require('lucide-react/dynamic');
16
+ var select = require('@base-ui/react/select');
17
+ var input = require('@base-ui/react/input');
18
+
19
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
20
+
21
+ var React__default = /*#__PURE__*/_interopDefault(React);
22
+
23
+ // src/hooks/use-table.ts
24
+ function cn(...inputs) {
25
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
26
+ }
27
+ var buttonVariants = classVarianceAuthority.cva(
28
+ "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
29
+ {
30
+ variants: {
31
+ variant: {
32
+ default: "bg-primary text-primary-foreground hover:bg-primary/80",
33
+ outline: "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
34
+ secondary: "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
35
+ ghost: "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
36
+ destructive: "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
37
+ link: "text-primary underline-offset-4 hover:underline"
38
+ },
39
+ size: {
40
+ default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
41
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
42
+ sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
43
+ lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
44
+ icon: "size-8",
45
+ "icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
46
+ "icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
47
+ "icon-lg": "size-9"
48
+ }
49
+ },
50
+ defaultVariants: {
51
+ variant: "default",
52
+ size: "default"
53
+ }
54
+ }
55
+ );
56
+ function Button({
57
+ className,
58
+ variant = "default",
59
+ size = "default",
60
+ ...props
61
+ }) {
62
+ return /* @__PURE__ */ jsxRuntime.jsx(
63
+ button.Button,
64
+ {
65
+ "data-slot": "button",
66
+ className: cn(buttonVariants({ variant, size, className })),
67
+ ...props
68
+ }
69
+ );
70
+ }
71
+ function DropdownMenu({ ...props }) {
72
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Root, { "data-slot": "dropdown-menu", ...props });
73
+ }
74
+ function DropdownMenuTrigger({ ...props }) {
75
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
76
+ }
77
+ function DropdownMenuContent({
78
+ align = "start",
79
+ alignOffset = 0,
80
+ side = "bottom",
81
+ sideOffset = 4,
82
+ className,
83
+ ...props
84
+ }) {
85
+ return /* @__PURE__ */ jsxRuntime.jsx(menu.Menu.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
86
+ menu.Menu.Positioner,
87
+ {
88
+ className: "isolate z-50 outline-none",
89
+ align,
90
+ alignOffset,
91
+ side,
92
+ sideOffset,
93
+ children: /* @__PURE__ */ jsxRuntime.jsx(
94
+ menu.Menu.Popup,
95
+ {
96
+ "data-slot": "dropdown-menu-content",
97
+ className: cn(
98
+ "z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95",
99
+ className
100
+ ),
101
+ ...props
102
+ }
103
+ )
104
+ }
105
+ ) });
106
+ }
107
+ function DropdownMenuItem({
108
+ className,
109
+ inset,
110
+ variant = "default",
111
+ ...props
112
+ }) {
113
+ return /* @__PURE__ */ jsxRuntime.jsx(
114
+ menu.Menu.Item,
115
+ {
116
+ "data-slot": "dropdown-menu-item",
117
+ "data-inset": inset,
118
+ "data-variant": variant,
119
+ className: cn(
120
+ "group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive",
121
+ className
122
+ ),
123
+ ...props
124
+ }
125
+ );
126
+ }
127
+ function ActionCell({ actions }) {
128
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-end gap-1", children: actions.map(
129
+ (item, idx) => item.type === "group" ? /* @__PURE__ */ jsxRuntime.jsx(ActionGroupDropdown, { group: item }, idx) : /* @__PURE__ */ jsxRuntime.jsx(ActionButton, { action: item }, item.key)
130
+ ) });
131
+ }
132
+ function ActionButton({ action }) {
133
+ function handleClick() {
134
+ if (action.disabled) return;
135
+ execute(action);
136
+ }
137
+ return /* @__PURE__ */ jsxRuntime.jsxs(
138
+ Button,
139
+ {
140
+ size: "sm",
141
+ onClick: handleClick,
142
+ disabled: action.disabled,
143
+ title: action.label,
144
+ variant: action.variant,
145
+ children: [
146
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon }),
147
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only sm:not-sr-only", children: action.label })
148
+ ]
149
+ }
150
+ );
151
+ }
152
+ function ActionGroupDropdown({ group }) {
153
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
154
+ /* @__PURE__ */ jsxRuntime.jsx(
155
+ DropdownMenuTrigger,
156
+ {
157
+ render: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", size: "icon", children: [
158
+ group.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: group.icon }),
159
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Open menu" })
160
+ ] })
161
+ }
162
+ ),
163
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { align: "end", className: "w-40", children: group.actions.map((action) => /* @__PURE__ */ jsxRuntime.jsxs(
164
+ DropdownMenuItem,
165
+ {
166
+ disabled: action.disabled,
167
+ variant: action.variant,
168
+ children: [
169
+ action.icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: action.icon }),
170
+ action.label
171
+ ]
172
+ },
173
+ action.key
174
+ )) })
175
+ ] });
176
+ }
177
+ function execute(action) {
178
+ if (!action.href) return;
179
+ if (action.method === "get") {
180
+ react.router.visit(action.href);
181
+ } else {
182
+ react.router.visit(action.href, { method: action.method });
183
+ }
184
+ }
185
+ function Icon({ name, size = 16 }) {
186
+ return /* @__PURE__ */ jsxRuntime.jsx(dynamic.DynamicIcon, { name, size });
187
+ }
188
+ function TableColumnHeader({
189
+ column,
190
+ title,
191
+ className
192
+ }) {
193
+ if (!column.getCanSort()) {
194
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(className), children: title });
195
+ }
196
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center gap-2", className), children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
197
+ /* @__PURE__ */ jsxRuntime.jsx(
198
+ DropdownMenuTrigger,
199
+ {
200
+ render: /* @__PURE__ */ jsxRuntime.jsxs(
201
+ Button,
202
+ {
203
+ variant: "ghost",
204
+ size: "sm",
205
+ className: "-ml-3 h-8 data-[state=open]:bg-accent",
206
+ children: [
207
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: title }),
208
+ column.getIsSorted() === "desc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, {}) : column.getIsSorted() === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, {}) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, {})
209
+ ]
210
+ }
211
+ )
212
+ }
213
+ ),
214
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "start", children: [
215
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => column.toggleSorting(false), children: [
216
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, {}),
217
+ "Asc"
218
+ ] }),
219
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => column.toggleSorting(true), children: [
220
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, {}),
221
+ "Desc"
222
+ ] })
223
+ ] })
224
+ ] }) });
225
+ }
226
+
227
+ // src/hooks/use-table.ts
228
+ function useTable({
229
+ table: serverData,
230
+ url,
231
+ searchDebounce = 300
232
+ }) {
233
+ const { data, columns: serverColumns, meta, state: serverState } = serverData;
234
+ const ctrl = React.useMemo(
235
+ () => new kineticsCore.TableController(serverState, meta),
236
+ [serverState, meta, url]
237
+ );
238
+ const [search, setSearchLocal] = React.useState(serverState.search ?? "");
239
+ const visit = React.useCallback(
240
+ (params) => {
241
+ react.router.get(url ?? window.location.pathname, params, {
242
+ preserveState: true,
243
+ preserveScroll: true,
244
+ replace: true
245
+ });
246
+ },
247
+ [url]
248
+ );
249
+ const handleSortChange = React.useCallback(
250
+ (updater) => {
251
+ const current = ctrl.toSorting();
252
+ const next = typeof updater === "function" ? updater(current) : updater;
253
+ visit(ctrl.resolveSort(next));
254
+ },
255
+ [ctrl, visit]
256
+ );
257
+ const handlePageChange = React.useCallback(
258
+ (updater) => {
259
+ const current = ctrl.toPagination();
260
+ const next = typeof updater === "function" ? updater(current) : updater;
261
+ visit(ctrl.resolvePagination(next));
262
+ },
263
+ [ctrl, visit]
264
+ );
265
+ const handleSearchChange = useDebounce.useDebouncedCallback((value) => {
266
+ visit(ctrl.resolveSearchParams(value));
267
+ }, searchDebounce);
268
+ const handleFilterChange = React.useCallback(
269
+ (key, value) => {
270
+ visit(ctrl.resolveFilterParams(key, value));
271
+ },
272
+ [ctrl, visit]
273
+ );
274
+ const columnDefs = React.useMemo(() => {
275
+ return serverColumns.filter((col) => col.visible).map((col) => {
276
+ if (col.type === "actions") {
277
+ return {
278
+ id: col.key,
279
+ accessorKey: col.key,
280
+ header: col.label,
281
+ enableSorting: false,
282
+ cell: ({ getValue }) => React__default.default.createElement(ActionCell, {
283
+ actions: getValue() ?? []
284
+ })
285
+ };
286
+ }
287
+ return {
288
+ id: col.key,
289
+ accessorKey: col.key,
290
+ header: ({ column }) => React__default.default.createElement(TableColumnHeader, {
291
+ column,
292
+ title: col.label
293
+ }),
294
+ enableSorting: col.sortable,
295
+ enableColumnFilter: col.filterable,
296
+ cell: ({ getValue }) => {
297
+ const value = getValue();
298
+ return kineticsCore.formatValue(value, col.type);
299
+ }
300
+ };
301
+ });
302
+ }, [serverColumns]);
303
+ const tableInstance = reactTable.useReactTable({
304
+ data,
305
+ columns: columnDefs,
306
+ state: {
307
+ sorting: ctrl.toSorting(),
308
+ pagination: ctrl.toPagination()
309
+ },
310
+ manualSorting: true,
311
+ manualPagination: true,
312
+ manualFiltering: true,
313
+ pageCount: meta.last_page,
314
+ onSortingChange: handleSortChange,
315
+ onPaginationChange: handlePageChange,
316
+ getCoreRowModel: reactTable.getCoreRowModel()
317
+ });
318
+ return {
319
+ tableInstance,
320
+ columns: serverColumns,
321
+ meta,
322
+ search,
323
+ setSearch: (value) => {
324
+ setSearchLocal(value);
325
+ handleSearchChange(value);
326
+ },
327
+ setFilter: handleFilterChange,
328
+ filters: serverState.filters
329
+ };
330
+ }
331
+ function Label({ className, ...props }) {
332
+ return /* @__PURE__ */ jsxRuntime.jsx(
333
+ "label",
334
+ {
335
+ "data-slot": "label",
336
+ className: cn(
337
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
338
+ className
339
+ ),
340
+ ...props
341
+ }
342
+ );
343
+ }
344
+ var Select = select.Select.Root;
345
+ function SelectGroup({ className, ...props }) {
346
+ return /* @__PURE__ */ jsxRuntime.jsx(
347
+ select.Select.Group,
348
+ {
349
+ "data-slot": "select-group",
350
+ className: cn("scroll-my-1 p-1", className),
351
+ ...props
352
+ }
353
+ );
354
+ }
355
+ function SelectValue({ className, ...props }) {
356
+ return /* @__PURE__ */ jsxRuntime.jsx(
357
+ select.Select.Value,
358
+ {
359
+ "data-slot": "select-value",
360
+ className: cn("flex flex-1 text-left", className),
361
+ ...props
362
+ }
363
+ );
364
+ }
365
+ function SelectTrigger({
366
+ className,
367
+ size = "default",
368
+ children,
369
+ ...props
370
+ }) {
371
+ return /* @__PURE__ */ jsxRuntime.jsxs(
372
+ select.Select.Trigger,
373
+ {
374
+ "data-slot": "select-trigger",
375
+ "data-size": size,
376
+ className: cn(
377
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
378
+ className
379
+ ),
380
+ ...props,
381
+ children: [
382
+ children,
383
+ /* @__PURE__ */ jsxRuntime.jsx(
384
+ select.Select.Icon,
385
+ {
386
+ render: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "pointer-events-none size-4 text-muted-foreground" })
387
+ }
388
+ )
389
+ ]
390
+ }
391
+ );
392
+ }
393
+ function SelectContent({
394
+ className,
395
+ children,
396
+ side = "bottom",
397
+ sideOffset = 4,
398
+ align = "center",
399
+ alignOffset = 0,
400
+ alignItemWithTrigger = true,
401
+ ...props
402
+ }) {
403
+ return /* @__PURE__ */ jsxRuntime.jsx(select.Select.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
404
+ select.Select.Positioner,
405
+ {
406
+ side,
407
+ sideOffset,
408
+ align,
409
+ alignOffset,
410
+ alignItemWithTrigger,
411
+ className: "isolate z-50",
412
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
413
+ select.Select.Popup,
414
+ {
415
+ "data-slot": "select-content",
416
+ "data-align-trigger": alignItemWithTrigger,
417
+ className: cn(
418
+ "relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
419
+ className
420
+ ),
421
+ ...props,
422
+ children: [
423
+ /* @__PURE__ */ jsxRuntime.jsx(SelectScrollUpButton, {}),
424
+ /* @__PURE__ */ jsxRuntime.jsx(select.Select.List, { children }),
425
+ /* @__PURE__ */ jsxRuntime.jsx(SelectScrollDownButton, {})
426
+ ]
427
+ }
428
+ )
429
+ }
430
+ ) });
431
+ }
432
+ function SelectItem({
433
+ className,
434
+ children,
435
+ ...props
436
+ }) {
437
+ return /* @__PURE__ */ jsxRuntime.jsxs(
438
+ select.Select.Item,
439
+ {
440
+ "data-slot": "select-item",
441
+ className: cn(
442
+ "relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
443
+ className
444
+ ),
445
+ ...props,
446
+ children: [
447
+ /* @__PURE__ */ jsxRuntime.jsx(select.Select.ItemText, { className: "flex flex-1 shrink-0 gap-2 whitespace-nowrap", children }),
448
+ /* @__PURE__ */ jsxRuntime.jsx(
449
+ select.Select.ItemIndicator,
450
+ {
451
+ render: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "pointer-events-none" }) })
452
+ }
453
+ )
454
+ ]
455
+ }
456
+ );
457
+ }
458
+ function SelectScrollUpButton({
459
+ className,
460
+ ...props
461
+ }) {
462
+ return /* @__PURE__ */ jsxRuntime.jsx(
463
+ select.Select.ScrollUpArrow,
464
+ {
465
+ "data-slot": "select-scroll-up-button",
466
+ className: cn(
467
+ "top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
468
+ className
469
+ ),
470
+ ...props,
471
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, {})
472
+ }
473
+ );
474
+ }
475
+ function SelectScrollDownButton({
476
+ className,
477
+ ...props
478
+ }) {
479
+ return /* @__PURE__ */ jsxRuntime.jsx(
480
+ select.Select.ScrollDownArrow,
481
+ {
482
+ "data-slot": "select-scroll-down-button",
483
+ className: cn(
484
+ "bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
485
+ className
486
+ ),
487
+ ...props,
488
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, {})
489
+ }
490
+ );
491
+ }
492
+ function TablePagination({
493
+ meta,
494
+ table
495
+ }) {
496
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
497
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 text-sm text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
498
+ "Showing ",
499
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: meta.from ?? 0 }),
500
+ "-",
501
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
502
+ " ",
503
+ meta.to ?? 0
504
+ ] }),
505
+ " of ",
506
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: meta.total }),
507
+ " ",
508
+ "results"
509
+ ] }) }),
510
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-6 lg:space-x-8", children: [
511
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden items-center gap-2 lg:flex", children: [
512
+ /* @__PURE__ */ jsxRuntime.jsx(Label, { htmlFor: "rows-per-page", className: "text-sm font-medium", children: "Rows per page" }),
513
+ /* @__PURE__ */ jsxRuntime.jsxs(
514
+ Select,
515
+ {
516
+ value: meta.per_page.toString(),
517
+ onValueChange: (value) => table.setPageSize(Number(value)),
518
+ children: [
519
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { size: "sm", className: "w-20", id: "rows-per-page", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: meta.per_page }) }),
520
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { side: "left", align: "end", children: [10, 15, 50, 100].map((pageSize) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: `${pageSize}`, children: pageSize }, pageSize)) })
521
+ ]
522
+ }
523
+ )
524
+ ] }),
525
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-fit items-center justify-center text-sm font-medium", children: [
526
+ "Page ",
527
+ meta.current_page,
528
+ " of ",
529
+ meta.last_page
530
+ ] }),
531
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "ml-auto flex items-center gap-2 lg:ml-0", children: [
532
+ /* @__PURE__ */ jsxRuntime.jsxs(
533
+ Button,
534
+ {
535
+ variant: "outline",
536
+ className: "hidden h-8 w-8 p-0 lg:flex",
537
+ onClick: () => table.firstPage(),
538
+ disabled: !table.getCanPreviousPage(),
539
+ children: [
540
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Go to first page" }),
541
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsLeft, {})
542
+ ]
543
+ }
544
+ ),
545
+ /* @__PURE__ */ jsxRuntime.jsxs(
546
+ Button,
547
+ {
548
+ variant: "outline",
549
+ className: "size-8",
550
+ size: "icon",
551
+ onClick: () => table.previousPage(),
552
+ disabled: !table.getCanPreviousPage(),
553
+ children: [
554
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Go to previous page" }),
555
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, {})
556
+ ]
557
+ }
558
+ ),
559
+ /* @__PURE__ */ jsxRuntime.jsxs(
560
+ Button,
561
+ {
562
+ variant: "outline",
563
+ className: "size-8",
564
+ size: "icon",
565
+ onClick: () => table.nextPage(),
566
+ disabled: !table.getCanNextPage(),
567
+ children: [
568
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Go to next page" }),
569
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, {})
570
+ ]
571
+ }
572
+ ),
573
+ /* @__PURE__ */ jsxRuntime.jsxs(
574
+ Button,
575
+ {
576
+ variant: "outline",
577
+ className: "hidden size-8 lg:flex",
578
+ size: "icon",
579
+ onClick: () => table.lastPage(),
580
+ disabled: !table.getCanNextPage(),
581
+ children: [
582
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Go to last page" }),
583
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsRight, {})
584
+ ]
585
+ }
586
+ )
587
+ ] })
588
+ ] })
589
+ ] });
590
+ }
591
+ function Input({ className, type, ...props }) {
592
+ return /* @__PURE__ */ jsxRuntime.jsx(
593
+ input.Input,
594
+ {
595
+ type,
596
+ "data-slot": "input",
597
+ className: cn(
598
+ "h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
599
+ className
600
+ ),
601
+ ...props
602
+ }
603
+ );
604
+ }
605
+ function TableToolbar({
606
+ search,
607
+ columns,
608
+ setSearch,
609
+ placeholder,
610
+ filters,
611
+ setFilter
612
+ }) {
613
+ const filterableColumns = columns.filter((c) => c.filterable);
614
+ const hasSearch = columns.some((c) => c.searchable);
615
+ const hasFilter = search || Object.keys(filters).length > 0;
616
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-1 items-center gap-2", children: [
617
+ hasSearch && /* @__PURE__ */ jsxRuntime.jsx(
618
+ Input,
619
+ {
620
+ placeholder,
621
+ value: search,
622
+ onChange: (e) => setSearch(e.target.value),
623
+ className: "h-8 w-37.5 lg:w-62.5"
624
+ }
625
+ ),
626
+ filterableColumns.map((col) => {
627
+ const options = Array.isArray(col.filterOptions) ? Object.fromEntries(col.filterOptions.map((o) => [o, o])) : col.filterOptions;
628
+ return /* @__PURE__ */ jsxRuntime.jsxs(
629
+ Select,
630
+ {
631
+ items: options,
632
+ value: filters[col.key] ?? "",
633
+ onValueChange: (e) => setFilter(col.key, e || null),
634
+ children: [
635
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: col.label }) }),
636
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: /* @__PURE__ */ jsxRuntime.jsxs(SelectGroup, { children: [
637
+ /* @__PURE__ */ jsxRuntime.jsxs(SelectItem, { value: "", children: [
638
+ "All ",
639
+ col.label
640
+ ] }),
641
+ Object.entries(options).map(([value, label]) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value, children: label }, value))
642
+ ] }) })
643
+ ]
644
+ }
645
+ );
646
+ }),
647
+ hasFilter && /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", children: [
648
+ "Reset",
649
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, {})
650
+ ] })
651
+ ] }) });
652
+ }
653
+ function Table({ className, ...props }) {
654
+ return /* @__PURE__ */ jsxRuntime.jsx(
655
+ "div",
656
+ {
657
+ "data-slot": "table-container",
658
+ className: "relative w-full overflow-x-auto",
659
+ children: /* @__PURE__ */ jsxRuntime.jsx(
660
+ "table",
661
+ {
662
+ "data-slot": "table",
663
+ className: cn("w-full caption-bottom text-sm", className),
664
+ ...props
665
+ }
666
+ )
667
+ }
668
+ );
669
+ }
670
+ function TableHeader({ className, ...props }) {
671
+ return /* @__PURE__ */ jsxRuntime.jsx(
672
+ "thead",
673
+ {
674
+ "data-slot": "table-header",
675
+ className: cn("[&_tr]:border-b", className),
676
+ ...props
677
+ }
678
+ );
679
+ }
680
+ function TableBody({ className, ...props }) {
681
+ return /* @__PURE__ */ jsxRuntime.jsx(
682
+ "tbody",
683
+ {
684
+ "data-slot": "table-body",
685
+ className: cn("[&_tr:last-child]:border-0", className),
686
+ ...props
687
+ }
688
+ );
689
+ }
690
+ function TableRow({ className, ...props }) {
691
+ return /* @__PURE__ */ jsxRuntime.jsx(
692
+ "tr",
693
+ {
694
+ "data-slot": "table-row",
695
+ className: cn(
696
+ "border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-muted",
697
+ className
698
+ ),
699
+ ...props
700
+ }
701
+ );
702
+ }
703
+ function TableHead({ className, ...props }) {
704
+ return /* @__PURE__ */ jsxRuntime.jsx(
705
+ "th",
706
+ {
707
+ "data-slot": "table-head",
708
+ className: cn(
709
+ "h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0",
710
+ className
711
+ ),
712
+ ...props
713
+ }
714
+ );
715
+ }
716
+ function TableCell({ className, ...props }) {
717
+ return /* @__PURE__ */ jsxRuntime.jsx(
718
+ "td",
719
+ {
720
+ "data-slot": "table-cell",
721
+ className: cn(
722
+ "p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0",
723
+ className
724
+ ),
725
+ ...props
726
+ }
727
+ );
728
+ }
729
+ function RenderTable({ table }) {
730
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-md border", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
731
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { className: "sticky top-0 z-10 bg-muted", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: headerGroup.headers.map((header) => {
732
+ return /* @__PURE__ */ jsxRuntime.jsx(TableHead, { colSpan: header.colSpan, children: header.isPlaceholder ? null : reactTable.flexRender(
733
+ header.column.columnDef.header,
734
+ header.getContext()
735
+ ) }, header.id);
736
+ }) }, headerGroup.id)) }),
737
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
738
+ TableRow,
739
+ {
740
+ "data-state": row.getIsSelected() && "selected",
741
+ children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: reactTable.flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))
742
+ },
743
+ row.id
744
+ )) : /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: /* @__PURE__ */ jsxRuntime.jsx(
745
+ TableCell,
746
+ {
747
+ colSpan: table.getAllColumns.length,
748
+ className: "h-24 text-center",
749
+ children: "No results."
750
+ }
751
+ ) }) })
752
+ ] }) });
753
+ }
754
+ function Table2({
755
+ table: serverData,
756
+ searchPlaceholder = "Search..."
757
+ }) {
758
+ const {
759
+ tableInstance,
760
+ columns: serverColumns,
761
+ meta,
762
+ search,
763
+ setSearch,
764
+ setFilter,
765
+ filters
766
+ } = useTable({ table: serverData });
767
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
768
+ /* @__PURE__ */ jsxRuntime.jsx(
769
+ TableToolbar,
770
+ {
771
+ search,
772
+ setSearch,
773
+ placeholder: searchPlaceholder,
774
+ columns: serverColumns,
775
+ filters,
776
+ setFilter
777
+ }
778
+ ),
779
+ /* @__PURE__ */ jsxRuntime.jsx(RenderTable, { table: tableInstance }),
780
+ /* @__PURE__ */ jsxRuntime.jsx(TablePagination, { meta, table: tableInstance })
781
+ ] });
782
+ }
783
+
784
+ exports.ActionCell = ActionCell;
785
+ exports.Table = Table2;
786
+ exports.useTable = useTable;
787
+ //# sourceMappingURL=index.cjs.map
788
+ //# sourceMappingURL=index.cjs.map