@adapttable/mantine 0.1.0

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,2004 @@
1
+ 'use strict';
2
+
3
+ var core = require('@adapttable/core');
4
+ var core$1 = require('@mantine/core');
5
+ var hooks = require('@mantine/hooks');
6
+ var react = require('react');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ // src/DataTable.tsx
10
+ function useMountStagger(ref, deps, options) {
11
+ const reduced = core.usePrefersReducedMotion();
12
+ const { enabled, step = 40, duration = 320 } = options;
13
+ const depsKey = deps.map(String).join("|");
14
+ react.useEffect(() => {
15
+ if (!enabled || reduced) return;
16
+ const root = ref.current;
17
+ if (!root) return;
18
+ const items = root.querySelectorAll("[data-stagger]");
19
+ items.forEach((el, index) => {
20
+ if (typeof el.animate !== "function") return;
21
+ el.animate(
22
+ [
23
+ { opacity: 0, transform: "translateY(8px)" },
24
+ { opacity: 1, transform: "translateY(0)" }
25
+ ],
26
+ {
27
+ duration,
28
+ delay: index * step,
29
+ easing: "cubic-bezier(0.16, 1, 0.3, 1)",
30
+ fill: "both"
31
+ }
32
+ );
33
+ });
34
+ }, [enabled, reduced, step, duration, ref, depsKey]);
35
+ }
36
+ function ActiveFilterChips({
37
+ chips,
38
+ onClearAll,
39
+ label,
40
+ clearAllLabel
41
+ }) {
42
+ if (chips.length === 0) return null;
43
+ return /* @__PURE__ */ jsxRuntime.jsxs(
44
+ core$1.Group,
45
+ {
46
+ gap: 6,
47
+ "aria-label": label,
48
+ component: "ul",
49
+ style: { listStyle: "none", padding: 0, margin: 0 },
50
+ children: [
51
+ chips.map((chip) => /* @__PURE__ */ jsxRuntime.jsx(
52
+ core$1.Pill,
53
+ {
54
+ component: "li",
55
+ withRemoveButton: true,
56
+ onRemove: chip.onRemove,
57
+ removeButtonProps: {
58
+ "aria-label": `${clearAllLabel}: ${chip.label}`
59
+ },
60
+ children: chip.label
61
+ },
62
+ chip.key
63
+ )),
64
+ onClearAll && /* @__PURE__ */ jsxRuntime.jsx(
65
+ core$1.Anchor,
66
+ {
67
+ component: "button",
68
+ type: "button",
69
+ fz: "xs",
70
+ fw: 600,
71
+ onClick: onClearAll,
72
+ children: clearAllLabel
73
+ }
74
+ )
75
+ ]
76
+ }
77
+ );
78
+ }
79
+ var asText = (value) => value == null ? "" : String(value);
80
+ var asList = (value) => {
81
+ if (value == null || value === "") return [];
82
+ return Array.isArray(value) ? value : [String(value)];
83
+ };
84
+ var asOp = (value) => core.RANGE_OPS.find((op) => op === value);
85
+ var RANGE_FLAVOUR = { numberRange: "number", dateRange: "date" };
86
+ function RangeField({
87
+ def,
88
+ source,
89
+ kind,
90
+ labels
91
+ }) {
92
+ const label = core.filterLabel(def);
93
+ const lowKey = def.key + core.RANGE_SUFFIXES[kind].start;
94
+ const highKey = def.key + core.RANGE_SUFFIXES[kind].end;
95
+ const derived = core.readRangeWidget(source.extra, lowKey, highKey);
96
+ const [chosen, setChosen] = react.useState(null);
97
+ const op = chosen ?? derived.op ?? null;
98
+ const low = asText(source.extra[lowKey]);
99
+ const high = asText(source.extra[highKey]);
100
+ const single = op === "lte" ? high : low;
101
+ const write = (nextOp, a, b) => source.setExtras(core.writeRangeWidget(nextOp, a, b, lowKey, highKey));
102
+ const handleOp = (value) => {
103
+ const next = asOp(value);
104
+ setChosen(next ?? null);
105
+ write(next, single, "");
106
+ };
107
+ const flavour = RANGE_FLAVOUR[kind];
108
+ const opLabelKeys = core.RANGE_OP_LABEL_KEYS[flavour];
109
+ const data = core.RANGE_OPS.map((value) => ({
110
+ value,
111
+ label: labels[opLabelKeys[value]]
112
+ }));
113
+ const valueInput = (text, value, commit) => flavour === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
114
+ core$1.NumberInput,
115
+ {
116
+ size: "sm",
117
+ hideControls: true,
118
+ style: { flex: "1 1 6rem", minWidth: "6rem" },
119
+ "aria-label": `${label} ${text}`,
120
+ placeholder: text,
121
+ value,
122
+ onChange: (next) => commit(String(next))
123
+ }
124
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
125
+ core$1.TextInput,
126
+ {
127
+ type: "date",
128
+ size: "sm",
129
+ style: { flex: "1 1 8.5rem", minWidth: "8.5rem" },
130
+ "aria-label": `${label} ${text}`,
131
+ placeholder: text,
132
+ value,
133
+ onChange: (e) => commit(e.currentTarget.value)
134
+ }
135
+ );
136
+ let values = null;
137
+ if (op === "between") {
138
+ values = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
139
+ valueInput(labels.from, low, (next) => write("between", next, high)),
140
+ valueInput(labels.to, high, (next) => write("between", low, next))
141
+ ] });
142
+ } else if (op) {
143
+ values = valueInput(labels.value, single, (next) => write(op, next, ""));
144
+ }
145
+ return /* @__PURE__ */ jsxRuntime.jsxs(core$1.Stack, { gap: 4, children: [
146
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Input.Label, { size: "sm", children: label }),
147
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { gap: "xs", align: "flex-start", children: [
148
+ /* @__PURE__ */ jsxRuntime.jsx(
149
+ core$1.Select,
150
+ {
151
+ size: "sm",
152
+ clearable: true,
153
+ style: { flex: "0 0 8.5rem", width: "8.5rem" },
154
+ "aria-label": `${label} ${labels.operator}`,
155
+ placeholder: labels.operator,
156
+ data,
157
+ value: op,
158
+ onChange: handleOp,
159
+ comboboxProps: { withinPortal: false }
160
+ }
161
+ ),
162
+ values
163
+ ] })
164
+ ] });
165
+ }
166
+ function SelectControl({
167
+ def,
168
+ source
169
+ }) {
170
+ const label = core.filterLabel(def);
171
+ const { options, loading } = core.useFilterOptions(def);
172
+ const data = loading ? [{ value: "", label: "\u2026", disabled: true }] : [{ value: "", label: "All" }, ...options];
173
+ return /* @__PURE__ */ jsxRuntime.jsx(
174
+ core$1.NativeSelect,
175
+ {
176
+ size: "sm",
177
+ label,
178
+ data,
179
+ value: asText(source.extra[def.key]),
180
+ onChange: (e) => source.setExtra(def.key, e.currentTarget.value)
181
+ }
182
+ );
183
+ }
184
+ function MultiSelectControl({
185
+ def,
186
+ source
187
+ }) {
188
+ const label = core.filterLabel(def);
189
+ const { options, loading } = core.useFilterOptions(def);
190
+ return /* @__PURE__ */ jsxRuntime.jsx(
191
+ core$1.Checkbox.Group,
192
+ {
193
+ label,
194
+ value: asList(source.extra[def.key]),
195
+ onChange: (values) => source.setExtra(def.key, values),
196
+ children: /* @__PURE__ */ jsxRuntime.jsx(core$1.Group, { gap: "sm", mt: 4, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(core$1.Loader, { size: "xs" }) : options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
197
+ core$1.Checkbox,
198
+ {
199
+ size: "sm",
200
+ value: option.value,
201
+ label: option.label
202
+ },
203
+ option.value
204
+ )) })
205
+ }
206
+ );
207
+ }
208
+ function FilterControl({
209
+ def,
210
+ source,
211
+ labels
212
+ }) {
213
+ switch (def.type) {
214
+ case "text":
215
+ return /* @__PURE__ */ jsxRuntime.jsx(
216
+ core$1.TextInput,
217
+ {
218
+ size: "sm",
219
+ label: core.filterLabel(def),
220
+ placeholder: def.placeholder,
221
+ value: asText(source.extra[def.key]),
222
+ onChange: (e) => source.setExtra(def.key, e.currentTarget.value)
223
+ }
224
+ );
225
+ case "select":
226
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectControl, { def, source });
227
+ case "multiSelect":
228
+ return /* @__PURE__ */ jsxRuntime.jsx(MultiSelectControl, { def, source });
229
+ case "dateRange":
230
+ case "numberRange":
231
+ return /* @__PURE__ */ jsxRuntime.jsx(RangeField, { def, source, kind: def.type, labels });
232
+ }
233
+ }
234
+ function AutoFilterForm({
235
+ defs,
236
+ source,
237
+ labels
238
+ }) {
239
+ return /* @__PURE__ */ jsxRuntime.jsx(core$1.Stack, { gap: "sm", children: defs.map((def) => /* @__PURE__ */ jsxRuntime.jsx(
240
+ FilterControl,
241
+ {
242
+ def,
243
+ source,
244
+ labels
245
+ },
246
+ def.key
247
+ )) });
248
+ }
249
+ function BulkActionBar({
250
+ selection,
251
+ total,
252
+ bulkActions,
253
+ confirm,
254
+ labels
255
+ }) {
256
+ const { selectedIds, selectedCount, clear, allMatching } = selection;
257
+ const { pending, run } = core.useBulkActionRunner({
258
+ confirm,
259
+ cancelLabel: labels.cancel,
260
+ onComplete: clear
261
+ });
262
+ if (selectedCount === 0) return null;
263
+ const ids = [...selectedIds];
264
+ return /* @__PURE__ */ jsxRuntime.jsxs(core$1.Stack, { gap: "xs", children: [
265
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { justify: "space-between", wrap: "wrap", gap: "sm", children: [
266
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "sm", children: labels.selectedCount(selectedCount) }),
267
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { gap: "xs", wrap: "wrap", children: [
268
+ /* @__PURE__ */ jsxRuntime.jsx(
269
+ core$1.Button,
270
+ {
271
+ size: "xs",
272
+ variant: "subtle",
273
+ onClick: clear,
274
+ disabled: pending !== null,
275
+ children: labels.clearAll
276
+ }
277
+ ),
278
+ bulkActions.map((action) => /* @__PURE__ */ jsxRuntime.jsx(
279
+ BulkButton,
280
+ {
281
+ action,
282
+ ids,
283
+ pending,
284
+ onRun: (a) => {
285
+ if (allMatching) run(a, ids, { allMatching: true, total });
286
+ else run(a, ids);
287
+ }
288
+ },
289
+ action.key
290
+ ))
291
+ ] })
292
+ ] }),
293
+ /* @__PURE__ */ jsxRuntime.jsx(ScopeBanner, { selection, total, labels })
294
+ ] });
295
+ }
296
+ function ScopeBanner({
297
+ selection,
298
+ total,
299
+ labels
300
+ }) {
301
+ if (selection.headerState !== "all" || total <= selection.visibleIds.length) {
302
+ return null;
303
+ }
304
+ return /* @__PURE__ */ jsxRuntime.jsx(core$1.Group, { role: "status", gap: "xs", wrap: "wrap", children: selection.allMatching ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
305
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "sm", children: labels.allMatchingSelected(total) }),
306
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Button, { size: "xs", variant: "subtle", onClick: selection.clear, children: labels.clearAll })
307
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
308
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "sm", children: labels.pageSelected(selection.selectedCount) }),
309
+ /* @__PURE__ */ jsxRuntime.jsx(
310
+ core$1.Button,
311
+ {
312
+ size: "xs",
313
+ variant: "light",
314
+ onClick: selection.selectAllMatching,
315
+ children: labels.selectAllMatching(total)
316
+ }
317
+ )
318
+ ] }) });
319
+ }
320
+ function BulkButton({
321
+ action,
322
+ ids,
323
+ pending,
324
+ onRun
325
+ }) {
326
+ const reason = core.resolveDisabledReason(action.disabledReason?.(ids));
327
+ const ineligible = reason !== void 0;
328
+ const button = /* @__PURE__ */ jsxRuntime.jsx(
329
+ core$1.Button,
330
+ {
331
+ size: "xs",
332
+ color: action.color,
333
+ leftSection: action.icon,
334
+ onClick: () => onRun(action),
335
+ loading: pending === action.key,
336
+ disabled: ineligible || pending !== null && pending !== action.key,
337
+ children: action.label
338
+ }
339
+ );
340
+ if (reason !== void 0) {
341
+ return /* @__PURE__ */ jsxRuntime.jsx(core$1.Tooltip, { label: reason, withArrow: true, openDelay: 150, children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: button }) });
342
+ }
343
+ return button;
344
+ }
345
+ function RowVisibility({
346
+ hidden,
347
+ name,
348
+ labels,
349
+ onToggle
350
+ }) {
351
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
352
+ /* @__PURE__ */ jsxRuntime.jsx(
353
+ core$1.ActionIcon,
354
+ {
355
+ variant: hidden ? "subtle" : "light",
356
+ color: hidden ? "gray" : "blue",
357
+ size: "sm",
358
+ "aria-label": `${hidden ? labels.showColumn : labels.hideColumn}: ${name}`,
359
+ "aria-pressed": !hidden,
360
+ onClick: onToggle,
361
+ children: /* @__PURE__ */ jsxRuntime.jsx(core.EyeIcon, { off: hidden })
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsxRuntime.jsx(
365
+ core$1.Text,
366
+ {
367
+ size: "sm",
368
+ style: { flex: 1 },
369
+ c: hidden ? "dimmed" : void 0,
370
+ td: hidden ? "line-through" : void 0,
371
+ children: name
372
+ }
373
+ )
374
+ ] });
375
+ }
376
+ function PinToggle({
377
+ pinned,
378
+ label,
379
+ onClick
380
+ }) {
381
+ return /* @__PURE__ */ jsxRuntime.jsx(
382
+ core$1.ActionIcon,
383
+ {
384
+ variant: pinned ? "filled" : "subtle",
385
+ color: pinned ? "blue" : "gray",
386
+ size: "sm",
387
+ "aria-label": label,
388
+ onClick,
389
+ children: /* @__PURE__ */ jsxRuntime.jsx(core.PinIcon, {})
390
+ }
391
+ );
392
+ }
393
+ function ActionsRow({
394
+ layout,
395
+ labels
396
+ }) {
397
+ const hidden = layout.isHidden(core.ACTIONS_COLUMN_KEY);
398
+ const pinned = layout.state.pinned[core.ACTIONS_COLUMN_KEY] === "right";
399
+ return /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { justify: "flex-start", wrap: "nowrap", gap: 6, px: 4, py: 2, children: [
400
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Box, { w: 22 }),
401
+ /* @__PURE__ */ jsxRuntime.jsx(
402
+ RowVisibility,
403
+ {
404
+ hidden,
405
+ name: labels.actions,
406
+ labels,
407
+ onToggle: () => layout.toggleVisible(core.ACTIONS_COLUMN_KEY)
408
+ }
409
+ ),
410
+ /* @__PURE__ */ jsxRuntime.jsx(
411
+ PinToggle,
412
+ {
413
+ pinned,
414
+ label: `${pinned ? labels.unpin : labels.pinRight}: ${labels.actions}`,
415
+ onClick: () => layout.setPinned(core.ACTIONS_COLUMN_KEY, pinned ? void 0 : "right")
416
+ }
417
+ )
418
+ ] });
419
+ }
420
+ function ColumnMenu({
421
+ allColumns,
422
+ layout,
423
+ labels,
424
+ hasRowActions = false
425
+ }) {
426
+ const drag = core.useColumnDragState();
427
+ return /* @__PURE__ */ jsxRuntime.jsxs(core$1.Menu, { closeOnItemClick: false, position: "bottom-end", withinPortal: true, children: [
428
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Menu.Target, { children: /* @__PURE__ */ jsxRuntime.jsx(core$1.Button, { variant: "default", size: "sm", children: labels.columns }) }),
429
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Menu.Dropdown, { children: /* @__PURE__ */ jsxRuntime.jsxs(core$1.Box, { p: 4, miw: 250, children: [
430
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", px: 4, pb: 6, children: labels.columns }),
431
+ core.columnMenuRows(allColumns, layout).map((r) => {
432
+ const indicator = drag.rowAttrs(r.key, r.index);
433
+ const edge = indicator["data-drop"];
434
+ const edgeOffset = edge === "before" ? "2px" : "-2px";
435
+ return /* @__PURE__ */ jsxRuntime.jsxs(
436
+ core$1.Group,
437
+ {
438
+ justify: "flex-start",
439
+ wrap: "nowrap",
440
+ gap: 6,
441
+ px: 4,
442
+ py: 2,
443
+ style: {
444
+ cursor: "grab",
445
+ opacity: "data-dragging" in indicator ? 0.4 : void 0,
446
+ boxShadow: edge ? `inset 0 ${edgeOffset} 0 0 var(--mantine-primary-color-filled)` : void 0
447
+ },
448
+ ...drag.rowDragProps(r.key, r.index),
449
+ ...drag.dropProps(r.index, layout.move),
450
+ ...indicator,
451
+ children: [
452
+ /* @__PURE__ */ jsxRuntime.jsx(
453
+ core$1.ActionIcon,
454
+ {
455
+ variant: "subtle",
456
+ color: "gray",
457
+ size: "sm",
458
+ style: { cursor: "grab" },
459
+ ...core.columnReorderKeyProps(
460
+ r.key,
461
+ r.index,
462
+ layout.move,
463
+ `${labels.moveLeft} / ${labels.moveRight}: ${r.name}`
464
+ ),
465
+ children: /* @__PURE__ */ jsxRuntime.jsx(core.GripIcon, {})
466
+ }
467
+ ),
468
+ /* @__PURE__ */ jsxRuntime.jsx(
469
+ RowVisibility,
470
+ {
471
+ hidden: r.hidden,
472
+ name: r.name,
473
+ labels,
474
+ onToggle: () => layout.toggleVisible(r.key)
475
+ }
476
+ ),
477
+ /* @__PURE__ */ jsxRuntime.jsx(
478
+ PinToggle,
479
+ {
480
+ pinned: r.pinned !== void 0,
481
+ label: `${core.pinActionLabel(r.pinned, labels)}: ${r.name}`,
482
+ onClick: () => layout.setPinned(r.key, core.nextPinSide(r.pinned))
483
+ }
484
+ )
485
+ ]
486
+ },
487
+ r.key
488
+ );
489
+ }),
490
+ hasRowActions && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
491
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Menu.Divider, {}),
492
+ /* @__PURE__ */ jsxRuntime.jsx(ActionsRow, { layout, labels })
493
+ ] }),
494
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Menu.Divider, {}),
495
+ /* @__PURE__ */ jsxRuntime.jsx(
496
+ core$1.Button,
497
+ {
498
+ variant: "subtle",
499
+ size: "xs",
500
+ fullWidth: true,
501
+ justify: "flex-start",
502
+ onClick: () => layout.reset(),
503
+ children: labels.resetColumns
504
+ }
505
+ )
506
+ ] }) })
507
+ ] });
508
+ }
509
+
510
+ // src/density.ts
511
+ var DENSITY_SPACING = {
512
+ comfortable: { verticalSpacing: "sm", horizontalSpacing: "md" },
513
+ compact: { verticalSpacing: 4, horizontalSpacing: "sm" }
514
+ };
515
+ function Svg({
516
+ size = 16,
517
+ className,
518
+ style,
519
+ children
520
+ }) {
521
+ return /* @__PURE__ */ jsxRuntime.jsx(
522
+ "svg",
523
+ {
524
+ width: size,
525
+ height: size,
526
+ viewBox: "0 0 24 24",
527
+ fill: "none",
528
+ stroke: "currentColor",
529
+ strokeWidth: 2,
530
+ strokeLinecap: "round",
531
+ strokeLinejoin: "round",
532
+ className,
533
+ style,
534
+ "aria-hidden": "true",
535
+ focusable: "false",
536
+ children
537
+ }
538
+ );
539
+ }
540
+ var SearchIcon = (p) => /* @__PURE__ */ jsxRuntime.jsxs(Svg, { ...p, children: [
541
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "7" }),
542
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m21 21-4.3-4.3" })
543
+ ] });
544
+ var ChevronUpIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx(Svg, { ...p, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 15 6-6 6 6" }) });
545
+ var ChevronDownIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx(Svg, { ...p, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" }) });
546
+ var ChevronRightIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx(Svg, { ...p, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 6 6 6-6 6" }) });
547
+ var SelectorIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx(Svg, { ...p, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m8 9 4-4 4 4M8 15l4 4 4-4" }) });
548
+ var CloseIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx(Svg, { ...p, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) });
549
+ var FiltersIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx(Svg, { ...p, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 6h16M7 12h10M10 18h4" }) });
550
+ var AlertIcon = (p) => /* @__PURE__ */ jsxRuntime.jsxs(Svg, { ...p, children: [
551
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" }),
552
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 9v4M12 17h.01" })
553
+ ] });
554
+ var RefreshIcon = (p) => /* @__PURE__ */ jsxRuntime.jsxs(Svg, { ...p, children: [
555
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-3-6.7L21 8" }),
556
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 3v5h-5" })
557
+ ] });
558
+ var InboxIcon = (p) => /* @__PURE__ */ jsxRuntime.jsxs(Svg, { ...p, children: [
559
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M22 12h-6l-2 3h-4l-2-3H2" }),
560
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.5 5.1 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.5-6.9A2 2 0 0 0 16.8 4H7.2a2 2 0 0 0-1.7 1.1Z" })
561
+ ] });
562
+ function ExpandToggle({
563
+ expanded,
564
+ expandLabel,
565
+ collapseLabel,
566
+ onToggle
567
+ }) {
568
+ return /* @__PURE__ */ jsxRuntime.jsx(
569
+ core$1.ActionIcon,
570
+ {
571
+ variant: "subtle",
572
+ color: "gray",
573
+ size: "sm",
574
+ "aria-expanded": expanded,
575
+ "aria-label": expanded ? collapseLabel : expandLabel,
576
+ onClick: onToggle,
577
+ children: /* @__PURE__ */ jsxRuntime.jsx(
578
+ ChevronRightIcon,
579
+ {
580
+ size: 14,
581
+ style: {
582
+ transform: expanded ? "rotate(90deg)" : "rotate(0deg)",
583
+ transition: "transform 150ms ease"
584
+ }
585
+ }
586
+ )
587
+ }
588
+ );
589
+ }
590
+ var RESIZE_HANDLE_STYLE = {
591
+ position: "absolute",
592
+ insetInlineEnd: 0,
593
+ top: 0,
594
+ height: "100%",
595
+ width: 8,
596
+ cursor: "col-resize",
597
+ touchAction: "none",
598
+ userSelect: "none"
599
+ };
600
+ function SortIcon({
601
+ active,
602
+ dir
603
+ }) {
604
+ if (!active) return /* @__PURE__ */ jsxRuntime.jsx(SelectorIcon, { size: 12 });
605
+ return dir === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(ChevronUpIcon, { size: 12 }) : /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { size: 12 });
606
+ }
607
+ function HeaderCell({
608
+ table,
609
+ column,
610
+ stickyStyle,
611
+ resizeHandle
612
+ }) {
613
+ const cellProps = table.getHeaderCellProps(column);
614
+ const headerStyle = {
615
+ ...cellProps.style,
616
+ ...stickyStyle
617
+ };
618
+ if (!column.sortable) {
619
+ return /* @__PURE__ */ jsxRuntime.jsxs(core$1.Table.Th, { ...cellProps, style: headerStyle, children: [
620
+ column.header,
621
+ resizeHandle
622
+ ] });
623
+ }
624
+ const buttonProps = table.getSortButtonProps(column);
625
+ const sortIndex = buttonProps["data-sort-index"];
626
+ const level = table.source.sortLevels.find((l) => l.key === column.key);
627
+ const active = level !== void 0 || table.sortBy === column.key;
628
+ return /* @__PURE__ */ jsxRuntime.jsxs(core$1.Table.Th, { ...cellProps, style: headerStyle, children: [
629
+ /* @__PURE__ */ jsxRuntime.jsxs(
630
+ core$1.Group,
631
+ {
632
+ component: "button",
633
+ gap: 6,
634
+ wrap: "nowrap",
635
+ display: "inline-flex",
636
+ style: {
637
+ background: "none",
638
+ border: 0,
639
+ cursor: "pointer",
640
+ font: "inherit",
641
+ padding: 0,
642
+ color: active ? "var(--mantine-primary-color-filled)" : "inherit"
643
+ },
644
+ ...buttonProps,
645
+ children: [
646
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: column.header }),
647
+ /* @__PURE__ */ jsxRuntime.jsx(SortIcon, { active, dir: level?.dir ?? table.sortDir }),
648
+ typeof sortIndex === "number" && /* @__PURE__ */ jsxRuntime.jsx(core$1.Badge, { component: "span", size: "xs", variant: "light", children: sortIndex })
649
+ ]
650
+ }
651
+ ),
652
+ resizeHandle
653
+ ] });
654
+ }
655
+ function RowActions({
656
+ row,
657
+ actions,
658
+ confirm,
659
+ cancelLabel
660
+ }) {
661
+ return /* @__PURE__ */ jsxRuntime.jsx(core$1.Group, { gap: 4, justify: "flex-end", wrap: "nowrap", children: actions.map((action) => {
662
+ if (action.isHidden?.(row)) return null;
663
+ const reason = core.resolveDisabledReason(action.disabledReason?.(row));
664
+ const disabled = reason !== void 0 || (action.isDisabled?.(row) ?? false);
665
+ const handleClick = disabled ? void 0 : (e) => {
666
+ e.stopPropagation();
667
+ core.runRowAction(action, row, confirm, cancelLabel);
668
+ };
669
+ return action.icon ? /* @__PURE__ */ jsxRuntime.jsx(
670
+ core$1.Tooltip,
671
+ {
672
+ label: reason ?? action.label,
673
+ withArrow: true,
674
+ openDelay: 200,
675
+ children: /* @__PURE__ */ jsxRuntime.jsx(
676
+ core$1.ActionIcon,
677
+ {
678
+ variant: "subtle",
679
+ color: action.color,
680
+ size: "sm",
681
+ disabled,
682
+ "aria-label": action.label,
683
+ onClick: handleClick,
684
+ children: action.icon
685
+ }
686
+ )
687
+ },
688
+ action.key
689
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
690
+ core$1.Button,
691
+ {
692
+ variant: "subtle",
693
+ color: action.color,
694
+ size: "compact-sm",
695
+ disabled,
696
+ onClick: handleClick,
697
+ children: action.label
698
+ },
699
+ action.key
700
+ );
701
+ }) });
702
+ }
703
+ var COMPARED_ROW_PROPS = [
704
+ "row",
705
+ "index",
706
+ "id",
707
+ "columns",
708
+ "getCellProps",
709
+ "selected",
710
+ "selectLabel",
711
+ "onToggleSelect",
712
+ "expanded",
713
+ "expandLabel",
714
+ "collapseLabel",
715
+ "onToggleExpand",
716
+ "renderRowDetail",
717
+ "columnSpan",
718
+ "rowActions",
719
+ "confirm",
720
+ "cancelLabel",
721
+ "onRowClick",
722
+ "prefetch",
723
+ "className",
724
+ "measureElement",
725
+ "pinSignature"
726
+ ];
727
+ function desktopRowPropsEqual(prev, next) {
728
+ return COMPARED_ROW_PROPS.every((key) => Object.is(prev[key], next[key]));
729
+ }
730
+ function leadingPinStyle(active, inset, zIndex, background) {
731
+ if (!active) return void 0;
732
+ const style = core.pinnedCellStyle({ side: "left", inset }, zIndex);
733
+ return background ? { ...style, background } : style;
734
+ }
735
+ function pinLayoutSignature(columns, pinOffset, hasLeftPin, actionsEdgePinned) {
736
+ const perColumn = columns.map((column) => {
737
+ const pin = pinOffset?.(column.key);
738
+ return pin ? `${column.key}:${pin.side}${pin.inset}` : column.key;
739
+ });
740
+ return `${perColumn.join("|")}|${String(hasLeftPin)}|${String(actionsEdgePinned)}`;
741
+ }
742
+ function DesktopRowBase({
743
+ row,
744
+ index,
745
+ id,
746
+ columns,
747
+ getCellProps,
748
+ selected,
749
+ selectLabel,
750
+ onToggleSelect,
751
+ expanded,
752
+ expandLabel,
753
+ collapseLabel,
754
+ onToggleExpand,
755
+ renderRowDetail,
756
+ columnSpan,
757
+ rowActions,
758
+ confirm,
759
+ cancelLabel,
760
+ onRowClick,
761
+ prefetch,
762
+ className,
763
+ measureElement,
764
+ pinStyleFor,
765
+ selectionCellStyle,
766
+ expansionCellStyle,
767
+ actionsCellStyle
768
+ }) {
769
+ const showActions = (rowActions?.length ?? 0) > 0;
770
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
771
+ /* @__PURE__ */ jsxRuntime.jsxs(
772
+ core$1.Table.Tr,
773
+ {
774
+ role: "row",
775
+ "data-index": index,
776
+ "aria-selected": selected,
777
+ ...core.rowClickProps(row, onRowClick),
778
+ className,
779
+ ref: measureElement,
780
+ "data-stagger": "",
781
+ onMouseEnter: prefetch ? () => prefetch(row) : void 0,
782
+ children: [
783
+ expanded !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Td, { ta: "center", style: expansionCellStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
784
+ ExpandToggle,
785
+ {
786
+ expanded,
787
+ expandLabel,
788
+ collapseLabel,
789
+ onToggle: () => onToggleExpand(id)
790
+ }
791
+ ) }),
792
+ selected !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Td, { ta: "center", style: selectionCellStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
793
+ core$1.Checkbox,
794
+ {
795
+ "aria-label": selectLabel,
796
+ checked: selected,
797
+ onChange: () => onToggleSelect(id)
798
+ }
799
+ ) }),
800
+ columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
801
+ core$1.Table.Td,
802
+ {
803
+ ...getCellProps(column),
804
+ style: pinStyleFor(column.key),
805
+ children: column.Cell ? /* @__PURE__ */ jsxRuntime.jsx(column.Cell, { row, rowIndex: index }) : column.accessor?.(row)
806
+ },
807
+ column.key
808
+ )),
809
+ showActions && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Td, { ta: "end", style: actionsCellStyle, children: /* @__PURE__ */ jsxRuntime.jsx(
810
+ RowActions,
811
+ {
812
+ row,
813
+ actions: rowActions,
814
+ confirm,
815
+ cancelLabel
816
+ }
817
+ ) })
818
+ ]
819
+ }
820
+ ),
821
+ expanded === true && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Tr, { children: /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Td, { colSpan: columnSpan, children: renderRowDetail(row) }) })
822
+ ] });
823
+ }
824
+ function DesktopTable({
825
+ table,
826
+ rows,
827
+ rowActions,
828
+ confirm,
829
+ prefetch,
830
+ onRowClick,
831
+ rowClassName,
832
+ renderRowDetail,
833
+ summaryRow,
834
+ expansion,
835
+ getRowId,
836
+ bodyRef,
837
+ className,
838
+ rowEntries,
839
+ paddingTop = 0,
840
+ paddingBottom = 0,
841
+ measureElement,
842
+ stickyHeaderOffset = 0,
843
+ stickyHeader = false,
844
+ pinOffset,
845
+ maxHeight,
846
+ virtualScrollRef,
847
+ setWidth,
848
+ columnWidths,
849
+ resizeLabel = "Resize column",
850
+ actionsPinned = false,
851
+ density = "comfortable"
852
+ }) {
853
+ const { columns, selection, labels, showActions, entries, columnSpan } = core.tableRenderModel({
854
+ table,
855
+ rows,
856
+ rowActions,
857
+ getRowId,
858
+ rowEntries,
859
+ renderRowDetail,
860
+ expansion
861
+ });
862
+ const expandable = expansion !== void 0;
863
+ const groupCells = core.headerGroupRow(columns);
864
+ const summaryCells = summaryRow?.(rows);
865
+ const hasRightPin = table.columns.some(
866
+ (c) => pinOffset?.(c.key)?.side === "right"
867
+ );
868
+ const actionsEdgePinned = showActions && (hasRightPin || actionsPinned);
869
+ const hasPinned = table.columns.some((c) => pinOffset?.(c.key) != null) || actionsEdgePinned;
870
+ const { ref: wrapperRef, overflowing } = core.useHorizontalOverflow();
871
+ const inScrollBox = maxHeight != null || hasPinned || overflowing;
872
+ const headerCellStyle = stickyHeader ? {
873
+ position: "sticky",
874
+ top: inScrollBox ? 0 : stickyHeaderOffset,
875
+ zIndex: core.PIN_Z.header,
876
+ background: "var(--mantine-color-body)",
877
+ boxShadow: "0 1px 0 var(--mantine-color-default-border)"
878
+ } : { background: "var(--mantine-color-body)" };
879
+ const expansionWidth = 36;
880
+ const selectionWidth = 40;
881
+ const actionsWidth = 120;
882
+ const expansionLead = expandable ? expansionWidth : 0;
883
+ const leads = {
884
+ left: expansionLead + (selection ? selectionWidth : 0),
885
+ right: showActions ? actionsWidth : 0
886
+ };
887
+ const hasLeftPin = table.columns.some(
888
+ (c) => pinOffset?.(c.key)?.side === "left"
889
+ );
890
+ const pinBg = "var(--mantine-color-body)";
891
+ const headerStyleFor = (column) => {
892
+ const key = column.key;
893
+ const pin = core.pinnedCellStyle(pinOffset?.(key), core.PIN_Z.headerPinned, leads);
894
+ const merged = {
895
+ ...headerCellStyle,
896
+ ...pin,
897
+ // A pinned column renders at the same width its sticky inset assumed,
898
+ // so stacked pins stay flush even with no declared width.
899
+ width: pin ? core.pinnedColumnWidth(column, columnWidths) : columnWidths?.[key]
900
+ };
901
+ if (setWidth && !merged.position) merged.position = "relative";
902
+ return merged;
903
+ };
904
+ const expansionHeaderStyle = {
905
+ ...headerCellStyle,
906
+ ...leadingPinStyle(hasLeftPin, 0, core.PIN_Z.headerPinned)
907
+ };
908
+ const selectionHeaderStyle = {
909
+ ...headerCellStyle,
910
+ ...leadingPinStyle(hasLeftPin, expansionLead, core.PIN_Z.headerPinned)
911
+ };
912
+ const actionsHeaderStyle = {
913
+ ...headerCellStyle,
914
+ ...core.edgePinStyle("right", actionsEdgePinned, core.PIN_Z.headerPinned)
915
+ };
916
+ const edgeBodyStyle = (side, active) => {
917
+ const pin = core.edgePinStyle(side, active, core.PIN_Z.body);
918
+ return pin ? { ...pin, background: pinBg } : void 0;
919
+ };
920
+ const expansionCellStyle = leadingPinStyle(hasLeftPin, 0, core.PIN_Z.body, pinBg);
921
+ const selectionCellStyle = leadingPinStyle(
922
+ hasLeftPin,
923
+ expansionLead,
924
+ core.PIN_Z.body,
925
+ pinBg
926
+ );
927
+ const actionsCellStyle = edgeBodyStyle("right", actionsEdgePinned);
928
+ const columnName = (column) => typeof column.header === "string" ? column.header : column.key;
929
+ const resizeHandleFor = (column) => setWidth ? /* @__PURE__ */ jsxRuntime.jsx(
930
+ "span",
931
+ {
932
+ ...core.columnResizeHandleProps(
933
+ column.key,
934
+ setWidth,
935
+ `${resizeLabel}: ${columnName(column)}`
936
+ ),
937
+ style: RESIZE_HANDLE_STYLE
938
+ }
939
+ ) : void 0;
940
+ const bodyPinStyle = (key) => {
941
+ const pin = core.pinnedCellStyle(pinOffset?.(key), core.PIN_Z.body, leads);
942
+ return pin ? { ...pin, background: pinBg } : void 0;
943
+ };
944
+ const { verticalSpacing, horizontalSpacing } = DENSITY_SPACING[density];
945
+ const minWidth = core.tableMinWidth(columns, {
946
+ widths: columnWidths,
947
+ extra: expansionLead + (selection ? 40 : 0) + (showActions ? 120 : 0)
948
+ });
949
+ const selectionRef = react.useRef(selection);
950
+ selectionRef.current = selection;
951
+ const toggleSelect = react.useCallback(
952
+ (id) => selectionRef.current.toggle(id),
953
+ []
954
+ );
955
+ const Row = react.useMemo(
956
+ () => react.memo(DesktopRowBase, desktopRowPropsEqual),
957
+ []
958
+ );
959
+ const pinSignature = pinLayoutSignature(
960
+ columns,
961
+ pinOffset,
962
+ hasLeftPin,
963
+ actionsEdgePinned
964
+ );
965
+ const wrapperStyle = maxHeight == null ? {
966
+ width: "100%",
967
+ ...hasPinned || overflowing ? { overflowX: "auto" } : {}
968
+ } : { width: "100%", maxHeight, overflow: "auto" };
969
+ return /* @__PURE__ */ jsxRuntime.jsx(
970
+ "div",
971
+ {
972
+ ref: (node) => {
973
+ wrapperRef(node);
974
+ virtualScrollRef?.(node);
975
+ },
976
+ style: wrapperStyle,
977
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
978
+ core$1.Table,
979
+ {
980
+ ...table.getTableProps(),
981
+ className,
982
+ highlightOnHover: true,
983
+ verticalSpacing,
984
+ horizontalSpacing,
985
+ miw: Math.max(480, minWidth),
986
+ children: [
987
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Table.Thead, { style: { background: "var(--mantine-color-body)" }, children: [
988
+ groupCells && /* @__PURE__ */ jsxRuntime.jsxs(core$1.Table.Tr, { children: [
989
+ expandable && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Th, {}),
990
+ selection && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Th, {}),
991
+ groupCells.map((cell) => /* @__PURE__ */ jsxRuntime.jsx(
992
+ core$1.Table.Th,
993
+ {
994
+ colSpan: cell.span,
995
+ ta: "center",
996
+ fw: 600,
997
+ style: {
998
+ borderBottom: "1px solid var(--mantine-color-default-border)"
999
+ },
1000
+ children: cell.label
1001
+ },
1002
+ cell.key
1003
+ )),
1004
+ showActions && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Th, {})
1005
+ ] }),
1006
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Table.Tr, { ...table.getHeaderRowProps(), children: [
1007
+ expandable && /* @__PURE__ */ jsxRuntime.jsx(
1008
+ core$1.Table.Th,
1009
+ {
1010
+ w: expansionWidth,
1011
+ ta: "center",
1012
+ style: expansionHeaderStyle,
1013
+ children: /* @__PURE__ */ jsxRuntime.jsx(core$1.VisuallyHidden, { children: labels.expandRow })
1014
+ }
1015
+ ),
1016
+ selection && /* @__PURE__ */ jsxRuntime.jsx(
1017
+ core$1.Table.Th,
1018
+ {
1019
+ w: selectionWidth,
1020
+ ta: "center",
1021
+ style: selectionHeaderStyle,
1022
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1023
+ core$1.Checkbox,
1024
+ {
1025
+ "aria-label": labels.selectAll,
1026
+ checked: selection.headerState === "all",
1027
+ indeterminate: selection.headerState === "some",
1028
+ onChange: selection.toggleAll
1029
+ }
1030
+ )
1031
+ }
1032
+ ),
1033
+ columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
1034
+ HeaderCell,
1035
+ {
1036
+ table,
1037
+ column,
1038
+ stickyStyle: headerStyleFor(column),
1039
+ resizeHandle: resizeHandleFor(column)
1040
+ },
1041
+ column.key
1042
+ )),
1043
+ showActions && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Th, { ta: "end", w: actionsWidth, style: actionsHeaderStyle, children: labels.actions })
1044
+ ] })
1045
+ ] }),
1046
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Table.Tbody, { ref: bodyRef, children: [
1047
+ paddingTop > 0 && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Tr, { "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
1048
+ core$1.Table.Td,
1049
+ {
1050
+ colSpan: columnSpan,
1051
+ style: { height: paddingTop, padding: 0 }
1052
+ }
1053
+ ) }),
1054
+ entries.map(({ row, index, key }) => {
1055
+ const id = getRowId(row);
1056
+ return /* @__PURE__ */ jsxRuntime.jsx(
1057
+ Row,
1058
+ {
1059
+ row,
1060
+ index,
1061
+ id,
1062
+ columns,
1063
+ getCellProps: table.getCellProps,
1064
+ selected: selection?.isSelected(id),
1065
+ selectLabel: labels.selectRow,
1066
+ onToggleSelect: toggleSelect,
1067
+ expanded: expansion?.isExpanded(id),
1068
+ expandLabel: labels.expandRow,
1069
+ collapseLabel: labels.collapseRow,
1070
+ onToggleExpand: expansion?.toggle,
1071
+ renderRowDetail,
1072
+ columnSpan,
1073
+ rowActions,
1074
+ confirm,
1075
+ cancelLabel: labels.cancel,
1076
+ onRowClick,
1077
+ prefetch,
1078
+ className: rowClassName?.(row, index),
1079
+ measureElement,
1080
+ pinStyleFor: bodyPinStyle,
1081
+ selectionCellStyle,
1082
+ expansionCellStyle,
1083
+ actionsCellStyle,
1084
+ pinSignature
1085
+ },
1086
+ key
1087
+ );
1088
+ }),
1089
+ paddingBottom > 0 && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Tr, { "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx(
1090
+ core$1.Table.Td,
1091
+ {
1092
+ colSpan: columnSpan,
1093
+ style: { height: paddingBottom, padding: 0 }
1094
+ }
1095
+ ) })
1096
+ ] }),
1097
+ summaryCells && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Tfoot, { children: /* @__PURE__ */ jsxRuntime.jsxs(core$1.Table.Tr, { children: [
1098
+ expandable && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Td, {}),
1099
+ selection && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Td, {}),
1100
+ columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
1101
+ core$1.Table.Td,
1102
+ {
1103
+ ...table.getCellProps(column),
1104
+ fw: 600,
1105
+ c: "dimmed",
1106
+ children: summaryCells[column.key]
1107
+ },
1108
+ column.key
1109
+ )),
1110
+ showActions && /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Td, {})
1111
+ ] }) })
1112
+ ]
1113
+ }
1114
+ )
1115
+ }
1116
+ );
1117
+ }
1118
+ function EmptyState({
1119
+ title,
1120
+ description,
1121
+ icon,
1122
+ action
1123
+ }) {
1124
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1125
+ core$1.Stack,
1126
+ {
1127
+ role: "status",
1128
+ align: "center",
1129
+ justify: "center",
1130
+ gap: 6,
1131
+ py: 48,
1132
+ px: 16,
1133
+ children: [
1134
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { c: "dimmed", "aria-hidden": true, children: icon ?? /* @__PURE__ */ jsxRuntime.jsx(InboxIcon, { size: 40 }) }),
1135
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fw: 600, fz: "md", children: title }),
1136
+ description && /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { c: "dimmed", fz: "sm", ta: "center", maw: 360, children: description }),
1137
+ action
1138
+ ]
1139
+ }
1140
+ );
1141
+ }
1142
+ function ErrorState({
1143
+ error,
1144
+ title,
1145
+ message,
1146
+ retryLabel,
1147
+ onRetry,
1148
+ isRetrying
1149
+ }) {
1150
+ return /* @__PURE__ */ jsxRuntime.jsx(
1151
+ core$1.Alert,
1152
+ {
1153
+ icon: /* @__PURE__ */ jsxRuntime.jsx(AlertIcon, { size: 16 }),
1154
+ color: "red",
1155
+ variant: "light",
1156
+ title,
1157
+ children: /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { justify: "space-between", align: "center", wrap: "nowrap", gap: "md", children: [
1158
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1159
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "sm", children: message }),
1160
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "xs", c: "dimmed", mt: 2, children: error.message })
1161
+ ] }),
1162
+ onRetry && /* @__PURE__ */ jsxRuntime.jsx(
1163
+ core$1.Button,
1164
+ {
1165
+ size: "xs",
1166
+ variant: "light",
1167
+ color: "red",
1168
+ leftSection: /* @__PURE__ */ jsxRuntime.jsx(RefreshIcon, { size: 14 }),
1169
+ onClick: onRetry,
1170
+ loading: isRetrying,
1171
+ children: retryLabel
1172
+ }
1173
+ )
1174
+ ] })
1175
+ }
1176
+ );
1177
+ }
1178
+ function FilterDrawer({
1179
+ opened,
1180
+ onClose,
1181
+ filters,
1182
+ activeFilterCount,
1183
+ onClearFilters,
1184
+ labels,
1185
+ dir = "ltr"
1186
+ }) {
1187
+ return /* @__PURE__ */ jsxRuntime.jsx(
1188
+ core$1.Drawer,
1189
+ {
1190
+ opened,
1191
+ onClose,
1192
+ position: dir === "rtl" ? "left" : "right",
1193
+ size: 380,
1194
+ title: labels.filters,
1195
+ overlayProps: { opacity: 0.4, blur: 2 },
1196
+ closeButtonProps: { "aria-label": labels.cancel },
1197
+ children: /* @__PURE__ */ jsxRuntime.jsxs(core$1.Stack, { gap: "md", mih: "60vh", justify: "space-between", children: [
1198
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Stack, { gap: "md", children: filters }),
1199
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { justify: "space-between", pt: "md", children: [
1200
+ /* @__PURE__ */ jsxRuntime.jsx(
1201
+ core$1.Button,
1202
+ {
1203
+ variant: "subtle",
1204
+ onClick: onClearFilters,
1205
+ disabled: activeFilterCount === 0,
1206
+ children: labels.clearAll
1207
+ }
1208
+ ),
1209
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Button, { onClick: onClose, children: labels.applyFilters })
1210
+ ] })
1211
+ ] })
1212
+ }
1213
+ );
1214
+ }
1215
+ function mobileLabel(column) {
1216
+ return column.mobileLabel ?? (typeof column.header === "string" ? column.header : column.key);
1217
+ }
1218
+ function MobileCards({
1219
+ table,
1220
+ rows,
1221
+ rowActions,
1222
+ confirm,
1223
+ getRowId,
1224
+ bodyRef,
1225
+ className,
1226
+ rowEntries,
1227
+ paddingTop = 0,
1228
+ paddingBottom = 0,
1229
+ measureElement,
1230
+ density = "comfortable",
1231
+ onRowClick,
1232
+ rowClassName,
1233
+ renderRowDetail,
1234
+ summaryRow,
1235
+ expansion
1236
+ }) {
1237
+ const { columns, selection, labels } = table;
1238
+ const compact = density === "compact";
1239
+ const cardPadding = compact ? "sm" : "md";
1240
+ const cardGap = compact ? 4 : "xs";
1241
+ const entries = rowEntries ?? rows.map((row, index) => ({
1242
+ row,
1243
+ index,
1244
+ key: getRowId(row)
1245
+ }));
1246
+ const summaryCells = summaryRow?.(rows);
1247
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1248
+ core$1.Stack,
1249
+ {
1250
+ gap: compact ? "xs" : "sm",
1251
+ ref: bodyRef,
1252
+ className,
1253
+ ...table.getTableProps({ role: "list" }),
1254
+ children: [
1255
+ paddingTop > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, style: { height: paddingTop } }),
1256
+ entries.map(({ row, index, key }) => {
1257
+ const id = getRowId(row);
1258
+ return /* @__PURE__ */ jsxRuntime.jsx(
1259
+ core$1.Card,
1260
+ {
1261
+ ...core.rowClickProps(row, onRowClick),
1262
+ className: rowClassName?.(row, index),
1263
+ ref: measureElement,
1264
+ "data-index": index,
1265
+ withBorder: true,
1266
+ radius: "md",
1267
+ padding: cardPadding,
1268
+ role: "listitem",
1269
+ "data-stagger": "",
1270
+ children: /* @__PURE__ */ jsxRuntime.jsxs(core$1.Stack, { gap: cardGap, children: [
1271
+ selection && /* @__PURE__ */ jsxRuntime.jsx(
1272
+ core$1.Checkbox,
1273
+ {
1274
+ "aria-label": labels.selectRow,
1275
+ checked: selection.isSelected(id),
1276
+ onChange: () => selection.toggle(id)
1277
+ }
1278
+ ),
1279
+ expansion && /* @__PURE__ */ jsxRuntime.jsx(core$1.Group, { justify: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
1280
+ ExpandToggle,
1281
+ {
1282
+ expanded: expansion.isExpanded(id),
1283
+ expandLabel: labels.expandRow,
1284
+ collapseLabel: labels.collapseRow,
1285
+ onToggle: () => expansion.toggle(id)
1286
+ }
1287
+ ) }),
1288
+ columns.map((column) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1289
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "xs", c: "dimmed", tt: "uppercase", fw: 500, children: mobileLabel(column) }),
1290
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { component: "div", fz: "sm", children: column.Cell ? /* @__PURE__ */ jsxRuntime.jsx(column.Cell, { row, rowIndex: index }) : column.accessor?.(row) })
1291
+ ] }, column.key)),
1292
+ expansion?.isExpanded(id) === true && /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderRowDetail(row) }),
1293
+ rowActions && rowActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(core$1.Group, { gap: 4, justify: "flex-end", pt: 4, children: rowActions.map((action) => {
1294
+ if (action.isHidden?.(row)) return null;
1295
+ const reason = core.resolveDisabledReason(
1296
+ action.disabledReason?.(row)
1297
+ );
1298
+ const disabled = reason !== void 0 || (action.isDisabled?.(row) ?? false);
1299
+ const run = disabled ? void 0 : () => core.runRowAction(action, row, confirm, labels.cancel);
1300
+ return action.icon ? /* @__PURE__ */ jsxRuntime.jsx(
1301
+ core$1.Tooltip,
1302
+ {
1303
+ label: reason ?? action.label,
1304
+ withArrow: true,
1305
+ openDelay: 200,
1306
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1307
+ core$1.ActionIcon,
1308
+ {
1309
+ variant: "subtle",
1310
+ color: action.color,
1311
+ size: "sm",
1312
+ disabled,
1313
+ "aria-label": action.label,
1314
+ onClick: run,
1315
+ children: action.icon
1316
+ }
1317
+ )
1318
+ },
1319
+ action.key
1320
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1321
+ core$1.Button,
1322
+ {
1323
+ variant: "subtle",
1324
+ color: action.color,
1325
+ size: "compact-sm",
1326
+ disabled,
1327
+ onClick: run,
1328
+ children: action.label
1329
+ },
1330
+ action.key
1331
+ );
1332
+ }) })
1333
+ ] })
1334
+ },
1335
+ key
1336
+ );
1337
+ }),
1338
+ paddingBottom > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": true, style: { height: paddingBottom } }),
1339
+ summaryCells && /* @__PURE__ */ jsxRuntime.jsx(core$1.Card, { withBorder: true, radius: "md", padding: cardPadding, role: "listitem", children: /* @__PURE__ */ jsxRuntime.jsx(core$1.Stack, { gap: cardGap, children: columns.filter((column) => summaryCells[column.key] !== void 0).map((column) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1340
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "xs", c: "dimmed", tt: "uppercase", fw: 500, children: mobileLabel(column) }),
1341
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { component: "div", fz: "sm", fw: 600, children: summaryCells[column.key] })
1342
+ ] }, column.key)) }) })
1343
+ ]
1344
+ }
1345
+ );
1346
+ }
1347
+ function PaginationFooter({
1348
+ page,
1349
+ totalPages,
1350
+ limit,
1351
+ total,
1352
+ fromIndex,
1353
+ toIndex,
1354
+ onPageChange,
1355
+ onLimitChange,
1356
+ labels
1357
+ }) {
1358
+ const safeTotalPages = Math.max(totalPages, 1);
1359
+ const safePage = Math.min(Math.max(page, 1), safeTotalPages);
1360
+ const options = core.pageSizeOptions(limit).map((n) => ({
1361
+ value: String(n),
1362
+ label: String(n)
1363
+ }));
1364
+ return /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { justify: "space-between", align: "center", wrap: "wrap", gap: "md", pt: "xs", children: [
1365
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { gap: "xs", align: "center", wrap: "nowrap", children: [
1366
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "xs", c: "dimmed", children: labels.rowsPerPage }),
1367
+ /* @__PURE__ */ jsxRuntime.jsx(
1368
+ core$1.Select,
1369
+ {
1370
+ "aria-label": labels.rowsPerPage,
1371
+ data: options,
1372
+ value: String(limit),
1373
+ onChange: (v) => onLimitChange(Number(v)),
1374
+ size: "xs",
1375
+ w: 76,
1376
+ allowDeselect: false,
1377
+ comboboxProps: { withinPortal: false }
1378
+ }
1379
+ ),
1380
+ total > 0 && /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "xs", c: "dimmed", children: labels.showing({ from: fromIndex, to: toIndex, total }) })
1381
+ ] }),
1382
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { gap: "sm", align: "center", wrap: "nowrap", children: [
1383
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "xs", c: "dimmed", children: labels.pageOf({ page: safePage, total: safeTotalPages }) }),
1384
+ /* @__PURE__ */ jsxRuntime.jsx(
1385
+ core$1.Pagination,
1386
+ {
1387
+ total: safeTotalPages,
1388
+ value: safePage,
1389
+ onChange: onPageChange,
1390
+ size: "sm",
1391
+ siblings: 1,
1392
+ boundaries: 1,
1393
+ getControlProps: (control) => ({
1394
+ "aria-label": control === "previous" ? labels.previousPage : labels.nextPage
1395
+ })
1396
+ }
1397
+ )
1398
+ ] })
1399
+ ] });
1400
+ }
1401
+ function SavedViewsMenu({
1402
+ views,
1403
+ labels
1404
+ }) {
1405
+ const [name, setName] = react.useState("");
1406
+ const trimmed = name.trim();
1407
+ const handleSave = () => {
1408
+ views.save(trimmed);
1409
+ setName("");
1410
+ };
1411
+ return /* @__PURE__ */ jsxRuntime.jsxs(core$1.Menu, { closeOnItemClick: false, position: "bottom-end", withinPortal: true, children: [
1412
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Menu.Target, { children: /* @__PURE__ */ jsxRuntime.jsx(core$1.Button, { variant: "default", size: "sm", children: labels.savedViews }) }),
1413
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Menu.Dropdown, { children: /* @__PURE__ */ jsxRuntime.jsxs(core$1.Box, { p: 4, miw: 220, children: [
1414
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { size: "xs", c: "dimmed", fw: 600, tt: "uppercase", px: 4, pb: 6, children: labels.savedViews }),
1415
+ views.views.map((view) => /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { gap: 6, px: 4, py: 2, wrap: "nowrap", children: [
1416
+ /* @__PURE__ */ jsxRuntime.jsx(
1417
+ core$1.Button,
1418
+ {
1419
+ variant: "subtle",
1420
+ size: "compact-sm",
1421
+ justify: "flex-start",
1422
+ style: { flex: 1 },
1423
+ onClick: () => views.apply(view.name),
1424
+ children: view.name
1425
+ }
1426
+ ),
1427
+ /* @__PURE__ */ jsxRuntime.jsx(
1428
+ core$1.ActionIcon,
1429
+ {
1430
+ variant: "subtle",
1431
+ color: "gray",
1432
+ size: "sm",
1433
+ "aria-label": `${labels.deleteView}: ${view.name}`,
1434
+ onClick: () => views.remove(view.name),
1435
+ children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, { size: 12 })
1436
+ }
1437
+ )
1438
+ ] }, view.name)),
1439
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Menu.Divider, {}),
1440
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { gap: 6, p: 4, wrap: "nowrap", children: [
1441
+ /* @__PURE__ */ jsxRuntime.jsx(
1442
+ core$1.TextInput,
1443
+ {
1444
+ size: "xs",
1445
+ style: { flex: 1 },
1446
+ placeholder: labels.viewName,
1447
+ value: name,
1448
+ onChange: (e) => setName(e.currentTarget.value)
1449
+ }
1450
+ ),
1451
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Button, { size: "xs", disabled: trimmed === "", onClick: handleSave, children: labels.saveView })
1452
+ ] })
1453
+ ] }) })
1454
+ ] });
1455
+ }
1456
+ function TableSkeleton({
1457
+ columns,
1458
+ rows = 5,
1459
+ loadingLabel
1460
+ }) {
1461
+ const colKeys = Array.from({ length: Math.max(columns, 1) }, (_, i) => i);
1462
+ const rowKeys = Array.from({ length: rows }, (_, i) => i);
1463
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "status", "aria-busy": "true", "aria-live": "polite", children: [
1464
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Table, { children: [
1465
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Thead, { children: /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Tr, { children: colKeys.map((c) => /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(
1466
+ core$1.Skeleton,
1467
+ {
1468
+ height: 12,
1469
+ radius: "sm",
1470
+ width: c === 0 ? "55%" : "40%"
1471
+ }
1472
+ ) }, c)) }) }),
1473
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Tbody, { children: rowKeys.map((r) => /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Tr, { children: colKeys.map((c) => /* @__PURE__ */ jsxRuntime.jsx(core$1.Table.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
1474
+ core$1.Skeleton,
1475
+ {
1476
+ height: 14,
1477
+ radius: "sm",
1478
+ width: c === 0 ? "70%" : "55%"
1479
+ }
1480
+ ) }, c)) }, r)) })
1481
+ ] }),
1482
+ loadingLabel ? /* @__PURE__ */ jsxRuntime.jsx(core$1.VisuallyHidden, { children: loadingLabel }) : null
1483
+ ] });
1484
+ }
1485
+ function FilterPopover({
1486
+ open,
1487
+ onClose,
1488
+ filters,
1489
+ activeFilterCount,
1490
+ onClearFilters,
1491
+ labels,
1492
+ dir = "ltr",
1493
+ children
1494
+ }) {
1495
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1496
+ core$1.Popover,
1497
+ {
1498
+ opened: open,
1499
+ onDismiss: onClose,
1500
+ position: dir === "rtl" ? "bottom-start" : "bottom-end",
1501
+ withinPortal: true,
1502
+ shadow: "md",
1503
+ radius: "md",
1504
+ width: 340,
1505
+ children: [
1506
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Popover.Target, { children }),
1507
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Popover.Dropdown, { children: [
1508
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { justify: "space-between", align: "center", mb: "sm", children: [
1509
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fw: 600, fz: "sm", children: labels.filters }),
1510
+ /* @__PURE__ */ jsxRuntime.jsx(
1511
+ core$1.Button,
1512
+ {
1513
+ variant: "subtle",
1514
+ size: "compact-xs",
1515
+ onClick: onClearFilters,
1516
+ disabled: activeFilterCount === 0,
1517
+ children: labels.clearAll
1518
+ }
1519
+ )
1520
+ ] }),
1521
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Stack, { gap: "md", children: filters })
1522
+ ] })
1523
+ ]
1524
+ }
1525
+ );
1526
+ }
1527
+ function Toolbar({
1528
+ table,
1529
+ hideSearch,
1530
+ searchPlaceholder,
1531
+ sortByOptions,
1532
+ customToolbar,
1533
+ hasFilters,
1534
+ activeFilterCount,
1535
+ onToggleFilters,
1536
+ onFiltersTriggerPointerDown,
1537
+ onCloseFilters,
1538
+ filtersOpen,
1539
+ filtersMode,
1540
+ filters,
1541
+ onClearFilters,
1542
+ dir,
1543
+ columnMenu,
1544
+ showRowsPerPage,
1545
+ className
1546
+ }) {
1547
+ const { labels, source } = table;
1548
+ const searchProps = table.getSearchInputProps(
1549
+ searchPlaceholder ? { placeholder: searchPlaceholder } : void 0
1550
+ );
1551
+ const sortOptions = sortByOptions ?? (table.isMobile ? table.sortByOptions : void 0);
1552
+ const filtersButton = /* @__PURE__ */ jsxRuntime.jsx(
1553
+ core$1.Button,
1554
+ {
1555
+ variant: "default",
1556
+ size: "sm",
1557
+ "aria-expanded": filtersMode === "popover" ? filtersOpen : void 0,
1558
+ "data-active": filtersOpen || void 0,
1559
+ leftSection: /* @__PURE__ */ jsxRuntime.jsx(FiltersIcon, { size: 16 }),
1560
+ rightSection: activeFilterCount > 0 ? /* @__PURE__ */ jsxRuntime.jsx(core$1.Badge, { size: "sm", circle: true, children: activeFilterCount }) : void 0,
1561
+ onPointerDown: onFiltersTriggerPointerDown,
1562
+ onClick: onToggleFilters,
1563
+ children: labels.filters
1564
+ }
1565
+ );
1566
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1567
+ core$1.Group,
1568
+ {
1569
+ gap: "sm",
1570
+ justify: "space-between",
1571
+ align: "center",
1572
+ className,
1573
+ children: [
1574
+ !hideSearch && /* @__PURE__ */ jsxRuntime.jsx(
1575
+ core$1.TextInput,
1576
+ {
1577
+ ...searchProps,
1578
+ leftSection: /* @__PURE__ */ jsxRuntime.jsx(SearchIcon, { size: 14 }),
1579
+ size: "sm",
1580
+ style: { flex: 1, minWidth: 160, maxWidth: 360 }
1581
+ }
1582
+ ),
1583
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { gap: "xs", align: "center", children: [
1584
+ sortOptions && sortOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1585
+ core$1.Select,
1586
+ {
1587
+ "aria-label": labels.sortBy,
1588
+ placeholder: labels.sortBy,
1589
+ data: sortOptions,
1590
+ value: source.sortBy ?? null,
1591
+ onChange: (v) => source.setSort(v ?? void 0, source.sortDir ?? "asc"),
1592
+ clearable: true,
1593
+ size: "sm",
1594
+ w: 160,
1595
+ comboboxProps: { withinPortal: false }
1596
+ }
1597
+ ),
1598
+ customToolbar,
1599
+ hasFilters && (filtersMode === "popover" ? /* @__PURE__ */ jsxRuntime.jsx(
1600
+ FilterPopover,
1601
+ {
1602
+ open: filtersOpen,
1603
+ onClose: onCloseFilters,
1604
+ filters,
1605
+ activeFilterCount,
1606
+ onClearFilters,
1607
+ labels,
1608
+ dir,
1609
+ children: filtersButton
1610
+ }
1611
+ ) : filtersButton),
1612
+ columnMenu,
1613
+ showRowsPerPage && /* @__PURE__ */ jsxRuntime.jsxs(core$1.Group, { gap: "xs", align: "center", children: [
1614
+ /* @__PURE__ */ jsxRuntime.jsx(core$1.Text, { fz: "xs", c: "dimmed", children: labels.rowsPerPage }),
1615
+ /* @__PURE__ */ jsxRuntime.jsx(
1616
+ core$1.Select,
1617
+ {
1618
+ "aria-label": labels.rowsPerPage,
1619
+ data: core.pageSizeOptions(source.limit).map((n) => ({
1620
+ value: String(n),
1621
+ label: String(n)
1622
+ })),
1623
+ value: String(source.limit),
1624
+ onChange: (v) => source.setLimit(Number(v)),
1625
+ size: "sm",
1626
+ w: 80,
1627
+ allowDeselect: false,
1628
+ comboboxProps: { withinPortal: false }
1629
+ }
1630
+ )
1631
+ ] })
1632
+ ] })
1633
+ ]
1634
+ }
1635
+ );
1636
+ }
1637
+ var stickyToolbarStyle = (top) => ({
1638
+ position: "sticky",
1639
+ top,
1640
+ zIndex: 3,
1641
+ background: "var(--mantine-color-body)",
1642
+ paddingBottom: "var(--mantine-spacing-xs)"
1643
+ });
1644
+ function ColumnMenuSlot({
1645
+ enabled,
1646
+ ...props
1647
+ }) {
1648
+ if (!enabled) return null;
1649
+ return /* @__PURE__ */ jsxRuntime.jsx(ColumnMenu, { ...props });
1650
+ }
1651
+ function SavedViewsSlot({
1652
+ options,
1653
+ labels
1654
+ }) {
1655
+ const views = core.useSavedViews(options);
1656
+ return /* @__PURE__ */ jsxRuntime.jsx(SavedViewsMenu, { views, labels });
1657
+ }
1658
+ function useResolvedTableProps(props) {
1659
+ const { source, runtime } = core.useTableData({
1660
+ locale: props.locale,
1661
+ source: props.source,
1662
+ data: props.data,
1663
+ total: props.total,
1664
+ loading: props.loading,
1665
+ onQueryChange: props.onQueryChange,
1666
+ columns: props.columns,
1667
+ filters: props.filters,
1668
+ urlKey: props.urlKey,
1669
+ adapter: props.urlSync === false ? void 0 : props.urlAdapter,
1670
+ enabled: props.urlSync
1671
+ });
1672
+ const labels = react.useMemo(() => core.resolveLabels(props.labels), [props.labels]);
1673
+ let filters;
1674
+ if (core.isDeclarativeFilters(props.filters) || props.filters === void 0) {
1675
+ filters = runtime.defs.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(AutoFilterForm, { defs: runtime.defs, source, labels }) : void 0;
1676
+ } else {
1677
+ filters = props.filters;
1678
+ }
1679
+ const filterLabels = react.useMemo(
1680
+ () => ({ ...runtime.filterLabels, ...props.filterLabels }),
1681
+ [runtime.filterLabels, props.filterLabels]
1682
+ );
1683
+ return { ...props, source, filters, filterLabels };
1684
+ }
1685
+ function DataTable(props) {
1686
+ const chromeProps = useResolvedTableProps(props);
1687
+ const {
1688
+ source,
1689
+ rowActions,
1690
+ searchPlaceholder,
1691
+ sortByOptions,
1692
+ dir,
1693
+ prefetch,
1694
+ hideSearch,
1695
+ filters,
1696
+ filtersMode = "popover",
1697
+ bulkActions,
1698
+ slots,
1699
+ classNames,
1700
+ toolbar: customToolbar,
1701
+ skeletonRows,
1702
+ stickyTop = 0,
1703
+ animate = false,
1704
+ stickyHeader = false,
1705
+ enableColumnMenu = false,
1706
+ savedViews
1707
+ } = chromeProps;
1708
+ const density = chromeProps.density ?? "comfortable";
1709
+ const chrome = core.useTableChrome(chromeProps);
1710
+ const { table, isMobile, confirm, getRowId } = chrome;
1711
+ const hasRowActions = (rowActions?.length ?? 0) > 0;
1712
+ const visibleRowActions = chrome.columnLayout.isHidden(core.ACTIONS_COLUMN_KEY) ? void 0 : rowActions;
1713
+ const actionsPinned = chrome.columnLayout.state.pinned[core.ACTIONS_COLUMN_KEY] === "right";
1714
+ const { virtualization, loadMoreRef, canLoadMore, virtualScrollRef } = core.useChromeBodyData(chrome, chromeProps);
1715
+ const [drawerOpened, setDrawerOpened] = react.useState(false);
1716
+ const filtersTrigger = core.useFilterTriggerToggle(drawerOpened, setDrawerOpened);
1717
+ const rootRef = react.useRef(null);
1718
+ const { ref: toolbarRef, height: toolbarHeight } = hooks.useElementSize();
1719
+ const desktopBodyRef = react.useRef(null);
1720
+ const mobileBodyRef = react.useRef(null);
1721
+ core.useChromeScrollReset(rootRef, chrome, chromeProps);
1722
+ useMountStagger(
1723
+ isMobile ? mobileBodyRef : desktopBodyRef,
1724
+ [virtualization.rows.length, isMobile],
1725
+ { enabled: animate }
1726
+ );
1727
+ let body;
1728
+ if (chrome.body === "skeleton") {
1729
+ body = slots?.skeleton ?? /* @__PURE__ */ jsxRuntime.jsx(
1730
+ TableSkeleton,
1731
+ {
1732
+ columns: table.columns.length || 1,
1733
+ rows: skeletonRows ?? source.limit,
1734
+ loadingLabel: table.labels.loading
1735
+ }
1736
+ );
1737
+ } else if (chrome.body === "empty") {
1738
+ body = slots?.empty ?? (chrome.emptyVariant === "noResults" ? /* @__PURE__ */ jsxRuntime.jsx(
1739
+ EmptyState,
1740
+ {
1741
+ title: table.labels.noResults,
1742
+ action: /* @__PURE__ */ jsxRuntime.jsx(core$1.Button, { variant: "light", size: "sm", onClick: chrome.clearFilters, children: table.labels.clearAll })
1743
+ }
1744
+ ) : /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { title: table.labels.noData }));
1745
+ } else if (chrome.body === "mobile") {
1746
+ body = /* @__PURE__ */ jsxRuntime.jsx(
1747
+ MobileCards,
1748
+ {
1749
+ table,
1750
+ rows: source.rows,
1751
+ rowActions: visibleRowActions,
1752
+ confirm,
1753
+ getRowId,
1754
+ onRowClick: props.onRowClick,
1755
+ rowClassName: props.rowClassName,
1756
+ renderRowDetail: props.renderRowDetail,
1757
+ summaryRow: props.summaryRow,
1758
+ expansion: chrome.detail?.expansion,
1759
+ bodyRef: mobileBodyRef,
1760
+ className: classNames?.card,
1761
+ rowEntries: virtualization.enabled ? virtualization.rows : void 0,
1762
+ paddingTop: virtualization.paddingTop,
1763
+ paddingBottom: virtualization.paddingBottom,
1764
+ measureElement: virtualization.measureElement,
1765
+ density
1766
+ }
1767
+ );
1768
+ } else {
1769
+ body = /* @__PURE__ */ jsxRuntime.jsx(
1770
+ DesktopTable,
1771
+ {
1772
+ table,
1773
+ rows: source.rows,
1774
+ rowActions: visibleRowActions,
1775
+ confirm,
1776
+ prefetch,
1777
+ onRowClick: props.onRowClick,
1778
+ rowClassName: props.rowClassName,
1779
+ renderRowDetail: props.renderRowDetail,
1780
+ summaryRow: props.summaryRow,
1781
+ expansion: chrome.detail?.expansion,
1782
+ getRowId,
1783
+ bodyRef: desktopBodyRef,
1784
+ className: classNames?.table,
1785
+ rowEntries: virtualization.enabled ? virtualization.rows : void 0,
1786
+ paddingTop: virtualization.paddingTop,
1787
+ paddingBottom: virtualization.paddingBottom,
1788
+ measureElement: virtualization.measureElement,
1789
+ stickyHeaderOffset: stickyTop + toolbarHeight,
1790
+ stickyHeader,
1791
+ pinOffset: chrome.columnLayout.pinOffset,
1792
+ actionsPinned,
1793
+ maxHeight: props.maxHeight,
1794
+ virtualScrollRef,
1795
+ setWidth: props.resizableColumns ? chrome.columnLayout.setWidth : void 0,
1796
+ columnWidths: chrome.columnLayout.state.widths,
1797
+ resizeLabel: table.labels.resizeColumn,
1798
+ density
1799
+ }
1800
+ );
1801
+ }
1802
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1803
+ core$1.Paper,
1804
+ {
1805
+ ref: rootRef,
1806
+ p: "xs",
1807
+ radius: "md",
1808
+ withBorder: true,
1809
+ dir,
1810
+ "aria-busy": chrome.isRefreshing || void 0,
1811
+ className: classNames?.root,
1812
+ children: [
1813
+ /* @__PURE__ */ jsxRuntime.jsxs(core$1.Stack, { gap: "xs", children: [
1814
+ /* @__PURE__ */ jsxRuntime.jsx(
1815
+ core$1.Box,
1816
+ {
1817
+ ref: toolbarRef,
1818
+ style: stickyToolbarStyle(stickyTop),
1819
+ className: classNames?.toolbar,
1820
+ children: /* @__PURE__ */ jsxRuntime.jsxs(core$1.Stack, { gap: "xs", children: [
1821
+ /* @__PURE__ */ jsxRuntime.jsx(
1822
+ Toolbar,
1823
+ {
1824
+ table,
1825
+ hideSearch,
1826
+ searchPlaceholder,
1827
+ sortByOptions,
1828
+ customToolbar,
1829
+ hasFilters: Boolean(filters),
1830
+ activeFilterCount: chrome.activeFilterCount,
1831
+ filtersMode,
1832
+ filters,
1833
+ filtersOpen: drawerOpened,
1834
+ onToggleFilters: filtersTrigger.onClick,
1835
+ onFiltersTriggerPointerDown: filtersTrigger.onPointerDown,
1836
+ onCloseFilters: () => setDrawerOpened(false),
1837
+ onClearFilters: chrome.clearFilters,
1838
+ dir,
1839
+ columnMenu: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1840
+ savedViews && /* @__PURE__ */ jsxRuntime.jsx(
1841
+ SavedViewsSlot,
1842
+ {
1843
+ options: {
1844
+ adapter: chromeProps.urlAdapter,
1845
+ urlKey: chromeProps.urlKey,
1846
+ ...savedViews
1847
+ },
1848
+ labels: table.labels
1849
+ }
1850
+ ),
1851
+ /* @__PURE__ */ jsxRuntime.jsx(
1852
+ ColumnMenuSlot,
1853
+ {
1854
+ enabled: enableColumnMenu && !isMobile,
1855
+ allColumns: chrome.allColumns,
1856
+ layout: chrome.columnLayout,
1857
+ labels: table.labels,
1858
+ hasRowActions
1859
+ }
1860
+ )
1861
+ ] }),
1862
+ showRowsPerPage: canLoadMore
1863
+ }
1864
+ ),
1865
+ /* @__PURE__ */ jsxRuntime.jsx(
1866
+ ActiveFilterChips,
1867
+ {
1868
+ chips: chrome.mergedChips,
1869
+ onClearAll: chrome.clearFilters,
1870
+ label: table.labels.filters,
1871
+ clearAllLabel: table.labels.clearAll
1872
+ }
1873
+ ),
1874
+ table.selection && bulkActions && /* @__PURE__ */ jsxRuntime.jsx(
1875
+ BulkActionBar,
1876
+ {
1877
+ selection: table.selection,
1878
+ total: source.total,
1879
+ bulkActions,
1880
+ confirm,
1881
+ labels: table.labels
1882
+ }
1883
+ )
1884
+ ] })
1885
+ }
1886
+ ),
1887
+ chrome.isRefreshing && /* @__PURE__ */ jsxRuntime.jsx(
1888
+ core$1.Progress,
1889
+ {
1890
+ size: "xs",
1891
+ animated: true,
1892
+ value: 100,
1893
+ "aria-label": table.labels.loading
1894
+ }
1895
+ ),
1896
+ source.error && /* @__PURE__ */ jsxRuntime.jsx(
1897
+ ErrorState,
1898
+ {
1899
+ error: source.error,
1900
+ title: table.labels.errorTitle,
1901
+ message: table.labels.errorMessage,
1902
+ retryLabel: table.labels.retry,
1903
+ onRetry: source.refetch ? () => void source.refetch?.() : void 0,
1904
+ isRetrying: source.isFetching
1905
+ }
1906
+ ),
1907
+ !source.error && body,
1908
+ canLoadMore && source.hasNextPage && /* @__PURE__ */ jsxRuntime.jsx(core$1.Group, { ref: loadMoreRef, justify: "center", py: "xs", children: /* @__PURE__ */ jsxRuntime.jsx(
1909
+ core$1.Button,
1910
+ {
1911
+ variant: "default",
1912
+ size: "sm",
1913
+ loading: source.isFetchingNextPage,
1914
+ onClick: () => source.fetchNextPage(),
1915
+ children: table.labels.loadMore
1916
+ }
1917
+ ) }),
1918
+ chrome.showFooter && /* @__PURE__ */ jsxRuntime.jsx(core$1.Box, { className: classNames?.footer, children: /* @__PURE__ */ jsxRuntime.jsx(
1919
+ PaginationFooter,
1920
+ {
1921
+ page: table.pagination.safePage,
1922
+ totalPages: table.pagination.totalPages,
1923
+ limit: source.limit,
1924
+ total: source.total,
1925
+ fromIndex: table.pagination.fromIndex,
1926
+ toIndex: table.pagination.toIndex,
1927
+ onPageChange: source.setPage,
1928
+ onLimitChange: source.setLimit,
1929
+ labels: table.labels
1930
+ }
1931
+ ) })
1932
+ ] }),
1933
+ filters && filtersMode === "drawer" && /* @__PURE__ */ jsxRuntime.jsx(
1934
+ FilterDrawer,
1935
+ {
1936
+ opened: drawerOpened,
1937
+ onClose: () => setDrawerOpened(false),
1938
+ filters,
1939
+ activeFilterCount: chrome.activeFilterCount,
1940
+ onClearFilters: chrome.clearFilters,
1941
+ labels: table.labels,
1942
+ dir
1943
+ }
1944
+ )
1945
+ ]
1946
+ }
1947
+ );
1948
+ }
1949
+
1950
+ Object.defineProperty(exports, "createHistoryAdapter", {
1951
+ enumerable: true,
1952
+ get: function () { return core.createHistoryAdapter; }
1953
+ });
1954
+ Object.defineProperty(exports, "createMemoryAdapter", {
1955
+ enumerable: true,
1956
+ get: function () { return core.createMemoryAdapter; }
1957
+ });
1958
+ Object.defineProperty(exports, "defaultConfirm", {
1959
+ enumerable: true,
1960
+ get: function () { return core.defaultConfirm; }
1961
+ });
1962
+ Object.defineProperty(exports, "defaultLabels", {
1963
+ enumerable: true,
1964
+ get: function () { return core.defaultLabels; }
1965
+ });
1966
+ Object.defineProperty(exports, "deriveSortByOptions", {
1967
+ enumerable: true,
1968
+ get: function () { return core.deriveSortByOptions; }
1969
+ });
1970
+ Object.defineProperty(exports, "getHistoryAdapter", {
1971
+ enumerable: true,
1972
+ get: function () { return core.getHistoryAdapter; }
1973
+ });
1974
+ Object.defineProperty(exports, "useBackendData", {
1975
+ enumerable: true,
1976
+ get: function () { return core.useBackendData; }
1977
+ });
1978
+ Object.defineProperty(exports, "useDataTable", {
1979
+ enumerable: true,
1980
+ get: function () { return core.useDataTable; }
1981
+ });
1982
+ Object.defineProperty(exports, "useFrontendData", {
1983
+ enumerable: true,
1984
+ get: function () { return core.useFrontendData; }
1985
+ });
1986
+ Object.defineProperty(exports, "useSavedViews", {
1987
+ enumerable: true,
1988
+ get: function () { return core.useSavedViews; }
1989
+ });
1990
+ Object.defineProperty(exports, "useTableUrlState", {
1991
+ enumerable: true,
1992
+ get: function () { return core.useTableUrlState; }
1993
+ });
1994
+ exports.ActiveFilterChips = ActiveFilterChips;
1995
+ exports.AutoFilterForm = AutoFilterForm;
1996
+ exports.DataTable = DataTable;
1997
+ exports.EmptyState = EmptyState;
1998
+ exports.ErrorState = ErrorState;
1999
+ exports.PaginationFooter = PaginationFooter;
2000
+ exports.SavedViewsMenu = SavedViewsMenu;
2001
+ exports.TableSkeleton = TableSkeleton;
2002
+ exports.useMountStagger = useMountStagger;
2003
+ //# sourceMappingURL=index.cjs.map
2004
+ //# sourceMappingURL=index.cjs.map