@arqel-dev/ui 0.13.0 → 0.15.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.
Files changed (68) hide show
  1. package/dist/ArqelCreatePage-MV4JN2MO.js +8 -0
  2. package/dist/{ArqelCreatePage-P3G6TKIK.js.map → ArqelCreatePage-MV4JN2MO.js.map} +1 -1
  3. package/dist/ArqelDashboardPage-QK3BYVK3.js +6 -0
  4. package/dist/{ArqelDashboardPage-PX3Y75AA.js.map → ArqelDashboardPage-QK3BYVK3.js.map} +1 -1
  5. package/dist/ArqelEditPage-7J3IS2BR.js +8 -0
  6. package/dist/{ArqelEditPage-HKQSE6E5.js.map → ArqelEditPage-7J3IS2BR.js.map} +1 -1
  7. package/dist/ArqelIndexPage-R6JL5KOH.js +12 -0
  8. package/dist/{ArqelIndexPage-MRH3572Z.js.map → ArqelIndexPage-R6JL5KOH.js.map} +1 -1
  9. package/dist/ArqelShowPage-5WWUSYC7.js +6 -0
  10. package/dist/{ArqelShowPage-4FS5MTUN.js.map → ArqelShowPage-5WWUSYC7.js.map} +1 -1
  11. package/dist/action.d.ts +1 -1
  12. package/dist/action.js +5 -5
  13. package/dist/{chunk-VSTRVXXZ.js → chunk-37FLEB4N.js} +4 -4
  14. package/dist/{chunk-VSTRVXXZ.js.map → chunk-37FLEB4N.js.map} +1 -1
  15. package/dist/chunk-3HN4ARGG.js +157 -0
  16. package/dist/chunk-3HN4ARGG.js.map +1 -0
  17. package/dist/{chunk-ERT7LL6C.js → chunk-4I5S6MH3.js} +12 -6
  18. package/dist/chunk-4I5S6MH3.js.map +1 -0
  19. package/dist/{chunk-PZEVKMZX.js → chunk-AZICSFBA.js} +218 -129
  20. package/dist/chunk-AZICSFBA.js.map +1 -0
  21. package/dist/{chunk-PXON56HL.js → chunk-BJER6TOI.js} +3 -3
  22. package/dist/{chunk-PXON56HL.js.map → chunk-BJER6TOI.js.map} +1 -1
  23. package/dist/{chunk-2LTZJ4R7.js → chunk-CVAMCRLL.js} +11 -6
  24. package/dist/chunk-CVAMCRLL.js.map +1 -0
  25. package/dist/{chunk-TNJEHYRF.js → chunk-FP5R6WED.js} +130 -24
  26. package/dist/chunk-FP5R6WED.js.map +1 -0
  27. package/dist/{chunk-FHRQ7PWE.js → chunk-H23VX3RR.js} +4 -3
  28. package/dist/chunk-H23VX3RR.js.map +1 -0
  29. package/dist/{chunk-47HD7ALI.js → chunk-HSDZM4AM.js} +3 -3
  30. package/dist/{chunk-47HD7ALI.js.map → chunk-HSDZM4AM.js.map} +1 -1
  31. package/dist/{chunk-MTZJDFQ6.js → chunk-MZMYV43C.js} +11 -7
  32. package/dist/chunk-MZMYV43C.js.map +1 -0
  33. package/dist/{chunk-6UJQP7KU.js → chunk-N5U2BB6T.js} +30 -116
  34. package/dist/chunk-N5U2BB6T.js.map +1 -0
  35. package/dist/{chunk-7LSZADUC.js → chunk-N6WLCHQE.js} +3 -3
  36. package/dist/{chunk-7LSZADUC.js.map → chunk-N6WLCHQE.js.map} +1 -1
  37. package/dist/{chunk-WKWV36PG.js → chunk-PSPJA5U6.js} +5 -3
  38. package/dist/chunk-PSPJA5U6.js.map +1 -0
  39. package/dist/{chunk-3JJOHYD7.js → chunk-UXN67E5L.js} +4 -4
  40. package/dist/{chunk-3JJOHYD7.js.map → chunk-UXN67E5L.js.map} +1 -1
  41. package/dist/{chunk-MSRTGCTJ.js → chunk-ZAM5TUPP.js} +59 -12
  42. package/dist/chunk-ZAM5TUPP.js.map +1 -0
  43. package/dist/form.d.ts +1 -1
  44. package/dist/form.js +3 -3
  45. package/dist/index.js +9 -9
  46. package/dist/pages.js +19 -19
  47. package/dist/resource.js +3 -3
  48. package/dist/shell.js +3 -3
  49. package/dist/table.js +2 -2
  50. package/dist/widgets.js +2 -2
  51. package/package.json +6 -6
  52. package/src/styles/globals.css +7 -0
  53. package/dist/ArqelCreatePage-P3G6TKIK.js +0 -8
  54. package/dist/ArqelDashboardPage-PX3Y75AA.js +0 -6
  55. package/dist/ArqelEditPage-HKQSE6E5.js +0 -8
  56. package/dist/ArqelIndexPage-MRH3572Z.js +0 -12
  57. package/dist/ArqelShowPage-4FS5MTUN.js +0 -6
  58. package/dist/chunk-2LTZJ4R7.js.map +0 -1
  59. package/dist/chunk-6UJQP7KU.js.map +0 -1
  60. package/dist/chunk-ERT7LL6C.js.map +0 -1
  61. package/dist/chunk-EYAUPJ6J.js +0 -64
  62. package/dist/chunk-EYAUPJ6J.js.map +0 -1
  63. package/dist/chunk-FHRQ7PWE.js.map +0 -1
  64. package/dist/chunk-MSRTGCTJ.js.map +0 -1
  65. package/dist/chunk-MTZJDFQ6.js.map +0 -1
  66. package/dist/chunk-PZEVKMZX.js.map +0 -1
  67. package/dist/chunk-TNJEHYRF.js.map +0 -1
  68. package/dist/chunk-WKWV36PG.js.map +0 -1
@@ -1,9 +1,10 @@
1
1
  import { resolveLucideIcon } from './chunk-RMPOR2YZ.js';
2
- import { Button } from './chunk-FHRQ7PWE.js';
2
+ import { Button } from './chunk-H23VX3RR.js';
3
3
  import { cn } from './chunk-B7ULUJVO.js';
4
- import { jsx, jsxs } from 'react/jsx-runtime';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';
6
6
  import { useRef, useMemo, useCallback } from 'react';
7
+ import { useArqelTranslations } from '@arqel-dev/react/utils';
7
8
 
8
9
  function TableCell({ column, value }) {
9
10
  switch (column.type) {
@@ -233,114 +234,201 @@ function DataTable({
233
234
  if (!sort || sort.column !== columnName) return null;
234
235
  return sort.direction === "desc" ? "desc" : "asc";
235
236
  };
236
- return /* @__PURE__ */ jsx("div", { className: cn("w-full overflow-x-auto", className), children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-sm", children: [
237
- /* @__PURE__ */ jsx("thead", { className: "sticky top-0 bg-background", children: table.getHeaderGroups().map((group) => /* @__PURE__ */ jsxs("tr", { className: "border-b border-border", children: [
238
- enableSelection && /* @__PURE__ */ jsx("th", { scope: "col", className: "w-10 px-3 py-2 text-left", children: /* @__PURE__ */ jsx(
239
- "input",
240
- {
241
- type: "checkbox",
242
- "aria-label": "Select all rows",
243
- checked: allSelected,
244
- ref: (el) => {
245
- if (el) el.indeterminate = someSelected;
246
- },
247
- onChange: toggleAll
248
- }
249
- ) }),
250
- group.headers.map((header) => {
251
- const col = visibleColumns.find((c) => c.name === header.column.id);
252
- const sortable = col?.sortable && onSortChange;
253
- const direction = headerSortDirection(header.column.id);
254
- return /* @__PURE__ */ jsx(
255
- "th",
256
- {
257
- scope: "col",
258
- className: cn(
259
- "px-3 py-2 text-left font-medium text-muted-foreground",
260
- col?.align === "center" && "text-center",
261
- col?.align === "end" && "text-right"
262
- ),
263
- "aria-sort": direction === "asc" ? "ascending" : direction === "desc" ? "descending" : "none",
264
- children: sortable ? /* @__PURE__ */ jsxs(
265
- "button",
266
- {
267
- type: "button",
268
- className: "inline-flex items-center gap-1 hover:text-foreground",
269
- onClick: () => onSortChange(header.column.id, direction === "asc" ? "desc" : "asc"),
270
- children: [
271
- flexRender(header.column.columnDef.header, header.getContext()),
272
- /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: direction === "asc" ? "\u25B2" : direction === "desc" ? "\u25BC" : "\u2195" })
273
- ]
274
- }
275
- ) : flexRender(header.column.columnDef.header, header.getContext())
276
- },
277
- header.id
278
- );
279
- }),
280
- rowActions && /* @__PURE__ */ jsx("th", { scope: "col", className: "w-24 px-3 py-2 text-right", "aria-label": "Actions" })
281
- ] }, group.id)) }),
282
- /* @__PURE__ */ jsxs("tbody", { children: [
283
- loading && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
284
- "td",
285
- {
286
- colSpan: visibleColumns.length + (enableSelection ? 1 : 0) + (rowActions ? 1 : 0),
287
- className: "px-3 py-4 text-center text-muted-foreground",
288
- children: "Loading\u2026"
289
- }
290
- ) }),
291
- !loading && records.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
292
- "td",
293
- {
294
- colSpan: visibleColumns.length + (enableSelection ? 1 : 0) + (rowActions ? 1 : 0),
295
- className: "px-3 py-8 text-center text-muted-foreground",
296
- children: emptyState ?? "No records found."
297
- }
298
- ) }),
299
- !loading && table.getRowModel().rows.map((row, index) => {
300
- const record = row.original;
301
- const checked = selectedIds.includes(record.id);
302
- return /* @__PURE__ */ jsxs(
303
- "tr",
237
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
238
+ /* @__PURE__ */ jsx("div", { className: cn("hidden w-full min-w-0 overflow-x-auto md:block", className), children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-sm", children: [
239
+ /* @__PURE__ */ jsx("thead", { className: "sticky top-0 bg-background", children: table.getHeaderGroups().map((group) => /* @__PURE__ */ jsxs("tr", { className: "border-b border-border", children: [
240
+ enableSelection && /* @__PURE__ */ jsx("th", { scope: "col", className: "w-10 px-3 py-2 text-left", children: /* @__PURE__ */ jsx(
241
+ "input",
304
242
  {
305
- "data-selected": checked || void 0,
306
- className: cn("border-b border-border", checked && "bg-muted"),
307
- children: [
308
- enableSelection && /* @__PURE__ */ jsx("td", { className: "w-10 px-3 py-2", children: /* @__PURE__ */ jsx(
309
- "input",
243
+ type: "checkbox",
244
+ "aria-label": "Select all rows",
245
+ checked: allSelected,
246
+ ref: (el) => {
247
+ if (el) el.indeterminate = someSelected;
248
+ },
249
+ onChange: toggleAll
250
+ }
251
+ ) }),
252
+ group.headers.map((header) => {
253
+ const col = visibleColumns.find((c) => c.name === header.column.id);
254
+ const sortable = col?.sortable && onSortChange;
255
+ const direction = headerSortDirection(header.column.id);
256
+ return /* @__PURE__ */ jsx(
257
+ "th",
258
+ {
259
+ scope: "col",
260
+ className: cn(
261
+ "px-3 py-2 text-left font-medium text-muted-foreground",
262
+ col?.align === "center" && "text-center",
263
+ col?.align === "end" && "text-right",
264
+ col?.hiddenOnMobile && "hidden md:table-cell"
265
+ ),
266
+ "aria-sort": direction === "asc" ? "ascending" : direction === "desc" ? "descending" : "none",
267
+ children: sortable ? /* @__PURE__ */ jsxs(
268
+ "button",
310
269
  {
311
- type: "checkbox",
312
- "aria-label": `Select row ${record.id}`,
313
- checked,
314
- onChange: (event) => {
315
- const native = event.nativeEvent;
316
- toggleRow(record.id, index, native.shiftKey === true);
317
- }
270
+ type: "button",
271
+ className: cn(
272
+ // -mx-3 px-3 stretches the button across the cell's
273
+ // horizontal padding; min-h-11 + w-full give a ≥44px
274
+ // touch target on mobile (WCAG 2.5.5) without changing
275
+ // the header's visual density.
276
+ "-mx-3 inline-flex min-h-11 w-full items-center gap-1 px-3 hover:text-foreground",
277
+ col?.align === "center" && "justify-center",
278
+ col?.align === "end" && "justify-end"
279
+ ),
280
+ onClick: () => onSortChange(header.column.id, direction === "asc" ? "desc" : "asc"),
281
+ children: [
282
+ flexRender(header.column.columnDef.header, header.getContext()),
283
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: direction === "asc" ? "\u25B2" : direction === "desc" ? "\u25BC" : "\u2195" })
284
+ ]
318
285
  }
319
- ) }),
320
- row.getVisibleCells().map((cell) => {
321
- const col = visibleColumns.find((c) => c.name === cell.column.id);
322
- return /* @__PURE__ */ jsx(
323
- "td",
286
+ ) : flexRender(header.column.columnDef.header, header.getContext())
287
+ },
288
+ header.id
289
+ );
290
+ }),
291
+ rowActions && /* @__PURE__ */ jsx("th", { scope: "col", className: "w-24 px-3 py-2 text-right", "aria-label": "Actions" })
292
+ ] }, group.id)) }),
293
+ /* @__PURE__ */ jsxs("tbody", { children: [
294
+ loading && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
295
+ "td",
296
+ {
297
+ colSpan: visibleColumns.length + (enableSelection ? 1 : 0) + (rowActions ? 1 : 0),
298
+ className: "px-3 py-4 text-center text-muted-foreground",
299
+ children: "Loading\u2026"
300
+ }
301
+ ) }),
302
+ !loading && records.length === 0 && /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
303
+ "td",
304
+ {
305
+ colSpan: visibleColumns.length + (enableSelection ? 1 : 0) + (rowActions ? 1 : 0),
306
+ className: "px-3 py-8 text-center text-muted-foreground",
307
+ children: emptyState ?? "No records found."
308
+ }
309
+ ) }),
310
+ !loading && table.getRowModel().rows.map((row, index) => {
311
+ const record = row.original;
312
+ const checked = selectedIds.includes(record.id);
313
+ return /* @__PURE__ */ jsxs(
314
+ "tr",
315
+ {
316
+ "data-selected": checked || void 0,
317
+ className: cn("border-b border-border", checked && "bg-muted"),
318
+ children: [
319
+ enableSelection && /* @__PURE__ */ jsx("td", { className: "w-10 px-3 py-2", children: /* @__PURE__ */ jsx(
320
+ "input",
324
321
  {
325
- className: cn(
326
- "px-3 py-2",
327
- col?.align === "center" && "text-center",
328
- col?.align === "end" && "text-right",
329
- col?.hiddenOnMobile && "hidden md:table-cell"
330
- ),
331
- children: flexRender(cell.column.columnDef.cell, cell.getContext())
332
- },
333
- cell.id
334
- );
335
- }),
336
- rowActions && /* @__PURE__ */ jsx("td", { className: "w-24 px-3 py-2 text-right", children: rowActions(record) })
337
- ]
338
- },
339
- row.id
340
- );
341
- })
342
- ] })
343
- ] }) });
322
+ type: "checkbox",
323
+ "aria-label": `Select row ${record.id}`,
324
+ checked,
325
+ onChange: (event) => {
326
+ const native = event.nativeEvent;
327
+ toggleRow(record.id, index, native.shiftKey === true);
328
+ }
329
+ }
330
+ ) }),
331
+ row.getVisibleCells().map((cell) => {
332
+ const col = visibleColumns.find((c) => c.name === cell.column.id);
333
+ return /* @__PURE__ */ jsx(
334
+ "td",
335
+ {
336
+ className: cn(
337
+ "px-3 py-2",
338
+ col?.align === "center" && "text-center",
339
+ col?.align === "end" && "text-right",
340
+ col?.hiddenOnMobile && "hidden md:table-cell"
341
+ ),
342
+ children: flexRender(cell.column.columnDef.cell, cell.getContext())
343
+ },
344
+ cell.id
345
+ );
346
+ }),
347
+ rowActions && /* @__PURE__ */ jsx("td", { className: "w-24 px-3 py-2 text-right", children: rowActions(record) })
348
+ ]
349
+ },
350
+ row.id
351
+ );
352
+ })
353
+ ] })
354
+ ] }) }),
355
+ /* @__PURE__ */ jsx(
356
+ DataCards,
357
+ {
358
+ columns: visibleColumns,
359
+ rows: table.getRowModel().rows,
360
+ enableSelection,
361
+ selectedIds,
362
+ onToggleRow: toggleRow,
363
+ rowActions,
364
+ loading,
365
+ emptyState
366
+ }
367
+ )
368
+ ] });
369
+ }
370
+ function DataCards({
371
+ columns,
372
+ rows,
373
+ enableSelection,
374
+ selectedIds,
375
+ onToggleRow,
376
+ rowActions,
377
+ loading,
378
+ emptyState
379
+ }) {
380
+ const cardColumns = columns.filter((col) => !col.hiddenOnMobile);
381
+ if (loading) {
382
+ return /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-center text-muted-foreground md:hidden", children: "Loading\u2026" });
383
+ }
384
+ if (rows.length === 0) {
385
+ return /* @__PURE__ */ jsx("div", { className: "px-3 py-8 text-center text-muted-foreground md:hidden", children: emptyState ?? "No records found." });
386
+ }
387
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3 md:hidden", children: rows.map((row, index) => {
388
+ const record = row.original;
389
+ const checked = selectedIds.includes(record.id);
390
+ return /* @__PURE__ */ jsxs(
391
+ "article",
392
+ {
393
+ "data-arqel-data-card": "",
394
+ "data-selected": checked || void 0,
395
+ className: cn("rounded-lg border border-border p-4 text-sm", checked && "bg-muted"),
396
+ children: [
397
+ (enableSelection || rowActions) && /* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center justify-between gap-2", children: [
398
+ enableSelection ? /* @__PURE__ */ jsx("label", { className: "-m-2.5 inline-flex size-11 cursor-pointer items-center justify-center p-2.5", children: /* @__PURE__ */ jsx(
399
+ "input",
400
+ {
401
+ type: "checkbox",
402
+ "aria-label": `Select row ${record.id}`,
403
+ className: "size-5",
404
+ checked,
405
+ onChange: (event) => {
406
+ const native = event.nativeEvent;
407
+ onToggleRow(record.id, index, native.shiftKey === true);
408
+ }
409
+ }
410
+ ) }) : /* @__PURE__ */ jsx("span", {}),
411
+ rowActions ? /* @__PURE__ */ jsx("div", { className: "ml-auto", children: rowActions(record) }) : null
412
+ ] }),
413
+ /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-[minmax(0,auto)_1fr] gap-x-3 gap-y-2", children: cardColumns.map((col) => /* @__PURE__ */ jsxs("div", { className: "contents", children: [
414
+ /* @__PURE__ */ jsx("dt", { className: "font-medium text-muted-foreground", children: col.label ?? col.name }),
415
+ /* @__PURE__ */ jsx(
416
+ "dd",
417
+ {
418
+ className: cn(
419
+ "min-w-0 break-words",
420
+ col.align === "end" && "text-right",
421
+ col.align === "center" && "text-center"
422
+ ),
423
+ children: /* @__PURE__ */ jsx(TableCell, { column: col, value: record[col.name] })
424
+ }
425
+ )
426
+ ] }, col.name)) })
427
+ ]
428
+ },
429
+ row.id
430
+ );
431
+ }) });
344
432
  }
345
433
  function TableFilters({
346
434
  filters,
@@ -349,6 +437,7 @@ function TableFilters({
349
437
  onClearAll,
350
438
  className
351
439
  }) {
440
+ const t = useArqelTranslations();
352
441
  if (filters.length === 0) return null;
353
442
  const activeCount = filters.reduce((acc, f) => {
354
443
  const v = values[f.name];
@@ -365,11 +454,7 @@ function TableFilters({
365
454
  },
366
455
  filter.name
367
456
  )),
368
- activeCount > 0 && onClearAll && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: onClearAll, children: [
369
- "Clear filters (",
370
- activeCount,
371
- ")"
372
- ] })
457
+ activeCount > 0 && onClearAll && /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: onClearAll, children: t("table.filters.clear", `Clear filters (${activeCount})`, { count: activeCount }) })
373
458
  ] });
374
459
  }
375
460
  function FilterControl({
@@ -393,7 +478,8 @@ function FilterControl({
393
478
  }
394
479
  function controlClasses() {
395
480
  return cn(
396
- "h-9 rounded-sm border border-[var(--input)]",
481
+ // 44px touch target on mobile (WCAG 2.5.5); dense 36px on >=md.
482
+ "h-11 rounded-sm border border-[var(--input)] md:h-9",
397
483
  "bg-background px-3 text-sm",
398
484
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
399
485
  );
@@ -403,6 +489,7 @@ function SelectFilter({
403
489
  value,
404
490
  onChange
405
491
  }) {
492
+ const t = useArqelTranslations();
406
493
  return /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1 text-xs text-muted-foreground", children: [
407
494
  filter.label ?? filter.name,
408
495
  /* @__PURE__ */ jsxs(
@@ -412,7 +499,7 @@ function SelectFilter({
412
499
  value: value === void 0 || value === null ? "" : String(value),
413
500
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value),
414
501
  children: [
415
- /* @__PURE__ */ jsx("option", { value: "", children: "All" }),
502
+ /* @__PURE__ */ jsx("option", { value: "", children: t("table.filters.all", "All") }),
416
503
  filter.props.options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
417
504
  ]
418
505
  }
@@ -431,7 +518,7 @@ function MultiSelectFilter({
431
518
  "select",
432
519
  {
433
520
  multiple: true,
434
- className: cn(controlClasses(), "h-auto min-h-[2.25rem] py-1"),
521
+ className: cn(controlClasses(), "h-auto min-h-11 py-1 md:min-h-[2.25rem]"),
435
522
  value: arr.map(String),
436
523
  onChange: (e) => {
437
524
  const next = Array.from(e.target.selectedOptions, (o) => o.value);
@@ -465,6 +552,7 @@ function TernaryFilter({
465
552
  value,
466
553
  onChange
467
554
  }) {
555
+ const t = useArqelTranslations();
468
556
  const current = value === void 0 || value === null ? "all" : String(value);
469
557
  return /* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1 text-xs text-muted-foreground", children: [
470
558
  filter.label ?? filter.name,
@@ -478,7 +566,7 @@ function TernaryFilter({
478
566
  onChange(v === "all" ? null : v);
479
567
  },
480
568
  children: [
481
- /* @__PURE__ */ jsx("option", { value: "all", children: filter.props.allLabel ?? "All" }),
569
+ /* @__PURE__ */ jsx("option", { value: "all", children: filter.props.allLabel ?? t("table.filters.all", "All") }),
482
570
  /* @__PURE__ */ jsx("option", { value: "true", children: filter.props.trueLabel ?? "Yes" }),
483
571
  /* @__PURE__ */ jsx("option", { value: "false", children: filter.props.falseLabel ?? "No" })
484
572
  ]
@@ -493,6 +581,7 @@ function TablePagination({
493
581
  perPageOptions = [10, 25, 50, 100],
494
582
  className
495
583
  }) {
584
+ const t = useArqelTranslations();
496
585
  const from = (meta.currentPage - 1) * meta.perPage + 1;
497
586
  const to = Math.min(meta.currentPage * meta.perPage, meta.total);
498
587
  const isFirst = meta.currentPage <= 1;
@@ -506,14 +595,14 @@ function TablePagination({
506
595
  ),
507
596
  "aria-label": "Pagination",
508
597
  children: [
509
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: meta.total === 0 ? "No results" : `${from}\u2013${to} of ${meta.total}` }),
598
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: meta.total === 0 ? t("table.empty", "No results") : `${from}\u2013${to} of ${meta.total}` }),
510
599
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
511
600
  onPerPageChange && /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
512
- "Per page",
601
+ t("table.per_page", "Per page"),
513
602
  /* @__PURE__ */ jsx(
514
603
  "select",
515
604
  {
516
- className: "h-8 rounded-sm border border-[var(--input)] bg-background px-2",
605
+ className: "h-11 rounded-sm border border-[var(--input)] bg-background px-2 md:h-8",
517
606
  value: meta.perPage,
518
607
  onChange: (e) => onPerPageChange(Number(e.target.value)),
519
608
  children: perPageOptions.map((n) => /* @__PURE__ */ jsx("option", { value: n, children: n }, n))
@@ -525,10 +614,11 @@ function TablePagination({
525
614
  {
526
615
  variant: "outline",
527
616
  size: "sm",
617
+ className: "h-11 md:h-8",
528
618
  disabled: isFirst,
529
619
  onClick: () => onPageChange(meta.currentPage - 1),
530
- "aria-label": "Previous page",
531
- children: "Prev"
620
+ "aria-label": t("table.pagination.previous_page", "Previous page"),
621
+ children: t("table.pagination.previous", "Prev")
532
622
  }
533
623
  ),
534
624
  /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
@@ -541,10 +631,11 @@ function TablePagination({
541
631
  {
542
632
  variant: "outline",
543
633
  size: "sm",
634
+ className: "h-11 md:h-8",
544
635
  disabled: isLast,
545
636
  onClick: () => onPageChange(meta.currentPage + 1),
546
- "aria-label": "Next page",
547
- children: "Next"
637
+ "aria-label": t("table.pagination.next_page", "Next page"),
638
+ children: t("table.pagination.next", "Next")
548
639
  }
549
640
  )
550
641
  ] })
@@ -560,6 +651,7 @@ function TableToolbar({
560
651
  onClearSelection,
561
652
  className
562
653
  }) {
654
+ const t = useArqelTranslations();
563
655
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-3 px-3 py-3", className), children: [
564
656
  /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-end gap-2", children: [
565
657
  search,
@@ -571,10 +663,7 @@ function TableToolbar({
571
663
  className: "flex flex-wrap items-center gap-2 rounded-sm border border-border bg-muted px-3 py-2",
572
664
  "aria-label": "Bulk actions",
573
665
  children: [
574
- /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium", children: [
575
- selectedCount,
576
- " selected"
577
- ] }),
666
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: t("table.bulk.selected", `${selectedCount} selected`, { count: selectedCount }) }),
578
667
  /* @__PURE__ */ jsxs("div", { className: "ml-auto flex flex-wrap items-center gap-2", children: [
579
668
  bulkActions,
580
669
  onClearSelection && /* @__PURE__ */ jsx(
@@ -583,7 +672,7 @@ function TableToolbar({
583
672
  type: "button",
584
673
  className: "text-sm text-muted-foreground hover:underline",
585
674
  onClick: onClearSelection,
586
- children: "Clear"
675
+ children: t("table.bulk.clear", "Clear")
587
676
  }
588
677
  )
589
678
  ] })
@@ -594,5 +683,5 @@ function TableToolbar({
594
683
  }
595
684
 
596
685
  export { DataTable, TableCell, TableFilters, TablePagination, TableToolbar };
597
- //# sourceMappingURL=chunk-PZEVKMZX.js.map
598
- //# sourceMappingURL=chunk-PZEVKMZX.js.map
686
+ //# sourceMappingURL=chunk-AZICSFBA.js.map
687
+ //# sourceMappingURL=chunk-AZICSFBA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/table/cells.tsx","../src/table/DataTable.tsx","../src/table/TableFilters.tsx","../src/table/TablePagination.tsx","../src/table/TableToolbar.tsx"],"names":["jsx","jsxs","useArqelTranslations"],"mappings":"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","file":"chunk-AZICSFBA.js","sourcesContent":["/**\n * Column cell renderers — one per `ColumnType` discriminant.\n *\n * `<TableCell column={column} value={...} record={...} />` dispatches on\n * `column.type` so DataTable stays free of polymorphic rendering. Cells\n * never reach into the network themselves; everything they need comes\n * from props serialised server-side.\n */\n\nimport type {\n BadgeColumnSchema,\n BooleanColumnSchema,\n ColumnSchema,\n ComputedColumnSchema,\n DateColumnSchema,\n IconColumnSchema,\n ImageColumnSchema,\n NumberColumnSchema,\n RelationshipColumnSchema,\n TextColumnSchema,\n} from '@arqel-dev/types/tables';\nimport { cn } from '../utils/cn.js';\nimport { resolveLucideIcon } from '../utils/icon.js';\n\nexport interface CellProps {\n column: ColumnSchema;\n value: unknown;\n}\n\nexport function TableCell({ column, value }: CellProps) {\n switch (column.type) {\n case 'text':\n return <TextCell column={column} value={value} />;\n case 'badge':\n return <BadgeCell column={column} value={value} />;\n case 'boolean':\n return <BooleanCell column={column} value={value} />;\n case 'date':\n return <DateCell column={column} value={value} />;\n case 'number':\n return <NumberCell column={column} value={value} />;\n case 'icon':\n return <IconCell column={column} />;\n case 'image':\n return <ImageCell column={column} value={value} />;\n case 'relationship':\n return <RelationshipCell column={column} value={value} />;\n case 'computed':\n return <ComputedCell column={column} value={value} />;\n }\n}\n\nfunction asString(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n\nfunction TextCell({ column, value }: { column: TextColumnSchema; value: unknown }) {\n const str = asString(value);\n const truncated =\n column.props.truncate && str.length > column.props.truncate\n ? `${str.slice(0, column.props.truncate)}…`\n : str;\n return (\n <span\n className={cn(\n column.props.weight === 'bold' && 'font-bold',\n column.props.weight === 'medium' && 'font-medium',\n )}\n >\n {truncated}\n </span>\n );\n}\n\n/**\n * Colour token → Tailwind classes for `BadgeColumn::colors()`.\n *\n * Tokens mirror the values the PHP producer emits (e.g. `'green'`,\n * `'yellow'`, `'blue'`). Classes are written out in full so Tailwind's\n * JIT can statically discover them. Unknown tokens fall back to muted.\n */\nconst BADGE_COLOR_CLASS: Record<string, string> = {\n gray: 'bg-muted text-foreground',\n slate: 'bg-slate-100 text-slate-800 dark:bg-slate-800/40 dark:text-slate-200',\n zinc: 'bg-zinc-100 text-zinc-800 dark:bg-zinc-800/40 dark:text-zinc-200',\n red: 'bg-red-100 text-red-800 dark:bg-red-900/40 dark:text-red-200',\n orange: 'bg-orange-100 text-orange-800 dark:bg-orange-900/40 dark:text-orange-200',\n amber: 'bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-200',\n yellow: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-200',\n lime: 'bg-lime-100 text-lime-800 dark:bg-lime-900/40 dark:text-lime-200',\n green: 'bg-green-100 text-green-800 dark:bg-green-900/40 dark:text-green-200',\n emerald: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-200',\n teal: 'bg-teal-100 text-teal-800 dark:bg-teal-900/40 dark:text-teal-200',\n cyan: 'bg-cyan-100 text-cyan-800 dark:bg-cyan-900/40 dark:text-cyan-200',\n sky: 'bg-sky-100 text-sky-800 dark:bg-sky-900/40 dark:text-sky-200',\n blue: 'bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-200',\n indigo: 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900/40 dark:text-indigo-200',\n violet: 'bg-violet-100 text-violet-800 dark:bg-violet-900/40 dark:text-violet-200',\n purple: 'bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-200',\n fuchsia: 'bg-fuchsia-100 text-fuchsia-800 dark:bg-fuchsia-900/40 dark:text-fuchsia-200',\n pink: 'bg-pink-100 text-pink-800 dark:bg-pink-900/40 dark:text-pink-200',\n rose: 'bg-rose-100 text-rose-800 dark:bg-rose-900/40 dark:text-rose-200',\n};\n\nconst BADGE_MUTED_CLASS = 'bg-muted text-foreground';\n\nfunction BadgeCell({ column, value }: { column: BadgeColumnSchema; value: unknown }) {\n const key = asString(value);\n const option = column.props.options?.find((o) => o.value === value);\n const label = option?.label ?? key;\n\n const colorToken = column.props.colors?.[key];\n const colorClass = (colorToken && BADGE_COLOR_CLASS[colorToken]) || BADGE_MUTED_CLASS;\n\n const iconName = column.props.icons?.[key];\n const Icon = iconName ? resolveLucideIcon(iconName) : undefined;\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium',\n column.props.pill ? 'rounded-full' : 'rounded-sm',\n colorClass,\n )}\n >\n {Icon ? <Icon className=\"size-3 shrink-0\" aria-hidden /> : null}\n {label}\n </span>\n );\n}\n\nfunction BooleanCell({ column, value }: { column: BooleanColumnSchema; value: unknown }) {\n const truthy = Boolean(value);\n return (\n <span role=\"img\" aria-label={truthy ? 'true' : 'false'}>\n {truthy ? (column.props.trueIcon ?? '✓') : (column.props.falseIcon ?? '—')}\n </span>\n );\n}\n\nfunction DateCell({ column, value }: { column: DateColumnSchema; value: unknown }) {\n if (!value) return <span className=\"text-muted-foreground\">—</span>;\n const raw = String(value);\n const date = new Date(raw);\n if (Number.isNaN(date.getTime())) return <span>{raw}</span>;\n if (column.props.mode === 'since') {\n return <time dateTime={date.toISOString()}>{formatRelative(date)}</time>;\n }\n if (column.props.mode === 'datetime') {\n return <time dateTime={date.toISOString()}>{date.toLocaleString()}</time>;\n }\n return <time dateTime={date.toISOString()}>{date.toLocaleDateString()}</time>;\n}\n\nfunction formatRelative(date: Date): string {\n const seconds = Math.round((Date.now() - date.getTime()) / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.round(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.round(hours / 24);\n return `${days}d ago`;\n}\n\nfunction NumberCell({ column, value }: { column: NumberColumnSchema; value: unknown }) {\n if (value === null || value === undefined) return <span>—</span>;\n const num = typeof value === 'number' ? value : Number(value);\n if (Number.isNaN(num)) return <span>{asString(value)}</span>;\n const formatted = num.toFixed(column.props.decimals ?? 0);\n const [whole, dec] = formatted.split('.');\n const safeWhole = whole ?? '0';\n const ts = column.props.thousandsSeparator;\n const finalWhole = ts ? safeWhole.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ts) : safeWhole;\n const ds = column.props.decimalSeparator ?? '.';\n return (\n <span>\n {column.props.prefix ?? ''}\n {finalWhole}\n {dec ? `${ds}${dec}` : ''}\n {column.props.suffix ?? ''}\n </span>\n );\n}\n\nfunction IconCell({ column }: { column: IconColumnSchema }) {\n return (\n <span role=\"img\" aria-label={column.props.icon} title={column.props.icon}>\n {column.props.icon}\n </span>\n );\n}\n\nfunction ImageCell({ column, value }: { column: ImageColumnSchema; value: unknown }) {\n const src = asString(value);\n if (!src) return null;\n const size = column.props.size ?? 32;\n return (\n <img\n src={src}\n alt=\"\"\n style={{ width: size, height: size }}\n className={cn(column.props.shape === 'circular' ? 'rounded-full' : 'rounded')}\n />\n );\n}\n\nfunction RelationshipCell({ column, value }: { column: RelationshipColumnSchema; value: unknown }) {\n if (value === null || value === undefined) return <span>—</span>;\n if (typeof value === 'object') {\n const attr = (value as Record<string, unknown>)[column.props.attribute];\n return <span>{asString(attr)}</span>;\n }\n return <span>{asString(value)}</span>;\n}\n\nfunction ComputedCell({ column, value }: { column: ComputedColumnSchema; value: unknown }) {\n if (value === null || value === undefined) {\n return <span className=\"text-muted-foreground\">{column.props.placeholder ?? '—'}</span>;\n }\n return <span>{asString(value)}</span>;\n}\n","/**\n * `<DataTable>` — generic table built on TanStack Table v8.\n *\n * Columns come from `ColumnSchema[]` (server-emitted). Two structural\n * extras live outside the schema list: a leading selection checkbox\n * (when `enableSelection`) and a trailing actions cell (when\n * `rowActions` resolver is provided).\n *\n * Selection model is controlled — pass `selectedIds` + `onSelectionChange`\n * — so callers (ResourceIndex, custom dashboards) keep ownership. Shift+\n * click on a row checkbox selects the range from the last clicked row,\n * matching the canonical Filament/Linear UX.\n */\n\nimport type { ColumnSchema, SortDirection, TableSort } from '@arqel-dev/types/tables';\nimport {\n type ColumnDef,\n flexRender,\n getCoreRowModel,\n type Row,\n useReactTable,\n} from '@tanstack/react-table';\nimport type { ReactNode } from 'react';\nimport { useCallback, useMemo, useRef } from 'react';\nimport { cn } from '../utils/cn.js';\nimport { TableCell } from './cells.js';\n\ntype RowId = string | number;\n\nexport interface DataTableRecord {\n id: RowId;\n [key: string]: unknown;\n}\n\nexport interface DataTableProps<TRecord extends DataTableRecord> {\n columns: ColumnSchema[];\n records: TRecord[];\n\n enableSelection?: boolean;\n selectedIds?: ReadonlyArray<RowId>;\n onSelectionChange?: ((ids: RowId[]) => void) | undefined;\n\n sort?: TableSort | null;\n onSortChange?: ((column: string, direction: SortDirection) => void) | undefined;\n\n rowActions?: ((record: TRecord) => ReactNode) | undefined;\n\n loading?: boolean;\n emptyState?: ReactNode;\n\n className?: string;\n}\n\nexport function DataTable<TRecord extends DataTableRecord>({\n columns,\n records,\n enableSelection = false,\n selectedIds = [],\n onSelectionChange,\n sort = null,\n onSortChange,\n rowActions,\n loading = false,\n emptyState,\n className,\n}: DataTableProps<TRecord>) {\n const lastClickedIndexRef = useRef<number | null>(null);\n\n const visibleColumns = useMemo(() => columns.filter((col) => !col.hidden), [columns]);\n\n const tableColumns = useMemo<ColumnDef<TRecord>[]>(\n () =>\n visibleColumns.map((col) => ({\n id: col.name,\n accessorFn: (row) => (row as Record<string, unknown>)[col.name],\n header: () => col.label ?? col.name,\n cell: (info) => <TableCell column={col} value={info.getValue()} />,\n enableSorting: col.sortable,\n })),\n [visibleColumns],\n );\n\n const table = useReactTable({\n data: records,\n columns: tableColumns,\n getCoreRowModel: getCoreRowModel(),\n });\n\n const allSelected =\n enableSelection && records.length > 0 && selectedIds.length === records.length;\n const someSelected =\n enableSelection && selectedIds.length > 0 && selectedIds.length < records.length;\n\n const toggleAll = useCallback(() => {\n if (!onSelectionChange) return;\n if (allSelected) onSelectionChange([]);\n else onSelectionChange(records.map((r) => r.id));\n }, [allSelected, records, onSelectionChange]);\n\n const toggleRow = useCallback(\n (id: RowId, index: number, shiftKey: boolean) => {\n if (!onSelectionChange) return;\n // `index` is the row's position in the core row-model, which today equals the\n // `records` prop order (only getCoreRowModel is wired — no client sort/filter\n // row model). The shift-range loop resolves ids from `records[i]`, so this\n // holds only while that ordering parity is true; revisit if a client-side\n // sorted/filtered row model is added.\n const set = new Set<RowId>(selectedIds);\n const lastIndex = lastClickedIndexRef.current;\n\n if (shiftKey && lastIndex !== null) {\n const [from, to] = lastIndex < index ? [lastIndex, index] : [index, lastIndex];\n const shouldSelect = !set.has(id);\n for (let i = from; i <= to; i++) {\n const rowId = records[i]?.id;\n if (rowId === undefined) continue;\n if (shouldSelect) set.add(rowId);\n else set.delete(rowId);\n }\n } else if (set.has(id)) {\n set.delete(id);\n } else {\n set.add(id);\n }\n\n lastClickedIndexRef.current = index;\n onSelectionChange(Array.from(set));\n },\n [records, selectedIds, onSelectionChange],\n );\n\n const headerSortDirection = (columnName: string): SortDirection | null => {\n if (!sort || sort.column !== columnName) return null;\n return sort.direction === 'desc' ? 'desc' : 'asc';\n };\n\n return (\n <>\n <div className={cn('hidden w-full min-w-0 overflow-x-auto md:block', className)}>\n <table className=\"w-full border-collapse text-sm\">\n <thead className=\"sticky top-0 bg-background\">\n {table.getHeaderGroups().map((group) => (\n <tr key={group.id} className=\"border-b border-border\">\n {enableSelection && (\n <th scope=\"col\" className=\"w-10 px-3 py-2 text-left\">\n <input\n type=\"checkbox\"\n aria-label=\"Select all rows\"\n checked={allSelected}\n ref={(el) => {\n if (el) el.indeterminate = someSelected;\n }}\n onChange={toggleAll}\n />\n </th>\n )}\n {group.headers.map((header) => {\n const col = visibleColumns.find((c) => c.name === header.column.id);\n const sortable = col?.sortable && onSortChange;\n const direction = headerSortDirection(header.column.id);\n return (\n <th\n key={header.id}\n scope=\"col\"\n className={cn(\n 'px-3 py-2 text-left font-medium text-muted-foreground',\n col?.align === 'center' && 'text-center',\n col?.align === 'end' && 'text-right',\n col?.hiddenOnMobile && 'hidden md:table-cell',\n )}\n aria-sort={\n direction === 'asc'\n ? 'ascending'\n : direction === 'desc'\n ? 'descending'\n : 'none'\n }\n >\n {sortable ? (\n <button\n type=\"button\"\n className={cn(\n // -mx-3 px-3 stretches the button across the cell's\n // horizontal padding; min-h-11 + w-full give a ≥44px\n // touch target on mobile (WCAG 2.5.5) without changing\n // the header's visual density.\n '-mx-3 inline-flex min-h-11 w-full items-center gap-1 px-3 hover:text-foreground',\n col?.align === 'center' && 'justify-center',\n col?.align === 'end' && 'justify-end',\n )}\n onClick={() =>\n onSortChange(header.column.id, direction === 'asc' ? 'desc' : 'asc')\n }\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n <span aria-hidden=\"true\">\n {direction === 'asc' ? '▲' : direction === 'desc' ? '▼' : '↕'}\n </span>\n </button>\n ) : (\n flexRender(header.column.columnDef.header, header.getContext())\n )}\n </th>\n );\n })}\n {rowActions && (\n <th scope=\"col\" className=\"w-24 px-3 py-2 text-right\" aria-label=\"Actions\" />\n )}\n </tr>\n ))}\n </thead>\n <tbody>\n {loading && (\n <tr>\n <td\n colSpan={visibleColumns.length + (enableSelection ? 1 : 0) + (rowActions ? 1 : 0)}\n className=\"px-3 py-4 text-center text-muted-foreground\"\n >\n Loading…\n </td>\n </tr>\n )}\n {!loading && records.length === 0 && (\n <tr>\n <td\n colSpan={visibleColumns.length + (enableSelection ? 1 : 0) + (rowActions ? 1 : 0)}\n className=\"px-3 py-8 text-center text-muted-foreground\"\n >\n {emptyState ?? 'No records found.'}\n </td>\n </tr>\n )}\n {!loading &&\n table.getRowModel().rows.map((row, index) => {\n const record = row.original;\n const checked = selectedIds.includes(record.id);\n return (\n <tr\n key={row.id}\n data-selected={checked || undefined}\n className={cn('border-b border-border', checked && 'bg-muted')}\n >\n {enableSelection && (\n <td className=\"w-10 px-3 py-2\">\n <input\n type=\"checkbox\"\n aria-label={`Select row ${record.id}`}\n checked={checked}\n onChange={(event) => {\n const native = event.nativeEvent as MouseEvent;\n toggleRow(record.id, index, native.shiftKey === true);\n }}\n />\n </td>\n )}\n {row.getVisibleCells().map((cell) => {\n const col = visibleColumns.find((c) => c.name === cell.column.id);\n return (\n <td\n key={cell.id}\n className={cn(\n 'px-3 py-2',\n col?.align === 'center' && 'text-center',\n col?.align === 'end' && 'text-right',\n col?.hiddenOnMobile && 'hidden md:table-cell',\n )}\n >\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n );\n })}\n {rowActions && (\n <td className=\"w-24 px-3 py-2 text-right\">{rowActions(record)}</td>\n )}\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n <DataCards\n columns={visibleColumns}\n rows={table.getRowModel().rows}\n enableSelection={enableSelection}\n selectedIds={selectedIds}\n onToggleRow={toggleRow}\n rowActions={rowActions}\n loading={loading}\n emptyState={emptyState}\n />\n </>\n );\n}\n\ninterface DataCardsProps<TRecord extends DataTableRecord> {\n columns: ColumnSchema[];\n rows: Row<TRecord>[];\n enableSelection: boolean;\n selectedIds: ReadonlyArray<RowId>;\n onToggleRow: (id: RowId, index: number, shiftKey: boolean) => void;\n rowActions?: ((record: TRecord) => ReactNode) | undefined;\n loading: boolean;\n emptyState?: ReactNode;\n}\n\nfunction DataCards<TRecord extends DataTableRecord>({\n columns,\n rows,\n enableSelection,\n selectedIds,\n onToggleRow,\n rowActions,\n loading,\n emptyState,\n}: DataCardsProps<TRecord>) {\n // hiddenOnMobile columns are dropped from the card body (same intent as the\n // table hiding them at < md).\n const cardColumns = columns.filter((col) => !col.hiddenOnMobile);\n\n if (loading) {\n return <div className=\"px-3 py-4 text-center text-muted-foreground md:hidden\">Loading…</div>;\n }\n if (rows.length === 0) {\n return (\n <div className=\"px-3 py-8 text-center text-muted-foreground md:hidden\">\n {emptyState ?? 'No records found.'}\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-3 md:hidden\">\n {rows.map((row, index) => {\n const record = row.original;\n const checked = selectedIds.includes(record.id);\n return (\n <article\n key={row.id}\n data-arqel-data-card=\"\"\n data-selected={checked || undefined}\n className={cn('rounded-lg border border-border p-4 text-sm', checked && 'bg-muted')}\n >\n {(enableSelection || rowActions) && (\n <div className=\"mb-3 flex items-center justify-between gap-2\">\n {enableSelection ? (\n <label className=\"-m-2.5 inline-flex size-11 cursor-pointer items-center justify-center p-2.5\">\n <input\n type=\"checkbox\"\n aria-label={`Select row ${record.id}`}\n className=\"size-5\"\n checked={checked}\n onChange={(event) => {\n const native = event.nativeEvent as MouseEvent;\n onToggleRow(record.id, index, native.shiftKey === true);\n }}\n />\n </label>\n ) : (\n <span />\n )}\n {rowActions ? <div className=\"ml-auto\">{rowActions(record)}</div> : null}\n </div>\n )}\n <dl className=\"grid grid-cols-[minmax(0,auto)_1fr] gap-x-3 gap-y-2\">\n {cardColumns.map((col) => (\n <div key={col.name} className=\"contents\">\n <dt className=\"font-medium text-muted-foreground\">{col.label ?? col.name}</dt>\n <dd\n className={cn(\n 'min-w-0 break-words',\n col.align === 'end' && 'text-right',\n col.align === 'center' && 'text-center',\n )}\n >\n <TableCell column={col} value={(record as Record<string, unknown>)[col.name]} />\n </dd>\n </div>\n ))}\n </dl>\n </article>\n );\n })}\n </div>\n );\n}\n","/**\n * `<TableFilters>` — renders one input per `FilterSchema` and emits\n * a single `onChange(name, value)` callback. Active values render as\n * dismissible chips so users can read state without re-opening menus.\n *\n * Phase 1 covers the four most-used filter types (select, multiSelect,\n * text, ternary). dateRange / scope land alongside FieldRenderer in\n * UI-004, where the date primitives ship.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type {\n FilterSchema,\n MultiSelectFilterSchema,\n SelectFilterSchema,\n TernaryFilterSchema,\n TextFilterSchema,\n} from '@arqel-dev/types/tables';\nimport { Button } from '../action/Button.js';\nimport { cn } from '../utils/cn.js';\n\nexport interface TableFiltersProps {\n filters: FilterSchema[];\n values: Record<string, unknown>;\n onChange: (name: string, value: unknown) => void;\n onClearAll?: (() => void) | undefined;\n className?: string | undefined;\n}\n\nexport function TableFilters({\n filters,\n values,\n onChange,\n onClearAll,\n className,\n}: TableFiltersProps) {\n const t = useArqelTranslations();\n if (filters.length === 0) return null;\n\n const activeCount = filters.reduce((acc, f) => {\n const v = values[f.name];\n return v !== undefined && v !== null && v !== '' ? acc + 1 : acc;\n }, 0);\n\n return (\n <fieldset className={cn('flex flex-wrap items-end gap-2 border-0 p-0', className)}>\n <legend className=\"sr-only\">Filters</legend>\n {filters.map((filter) => (\n <FilterControl\n key={filter.name}\n filter={filter}\n value={values[filter.name]}\n onChange={(v) => onChange(filter.name, v)}\n />\n ))}\n {activeCount > 0 && onClearAll && (\n <Button variant=\"ghost\" size=\"sm\" onClick={onClearAll}>\n {t('table.filters.clear', `Clear filters (${activeCount})`, { count: activeCount })}\n </Button>\n )}\n </fieldset>\n );\n}\n\nfunction FilterControl({\n filter,\n value,\n onChange,\n}: {\n filter: FilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n switch (filter.type) {\n case 'select':\n return <SelectFilter filter={filter} value={value} onChange={onChange} />;\n case 'multiSelect':\n return <MultiSelectFilter filter={filter} value={value} onChange={onChange} />;\n case 'text':\n return <TextFilter filter={filter} value={value} onChange={onChange} />;\n case 'ternary':\n return <TernaryFilter filter={filter} value={value} onChange={onChange} />;\n case 'dateRange':\n case 'scope':\n return null;\n }\n}\n\nfunction controlClasses() {\n return cn(\n // 44px touch target on mobile (WCAG 2.5.5); dense 36px on >=md.\n 'h-11 rounded-sm border border-[var(--input)] md:h-9',\n 'bg-background px-3 text-sm',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n );\n}\n\nfunction SelectFilter({\n filter,\n value,\n onChange,\n}: {\n filter: SelectFilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const t = useArqelTranslations();\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {filter.label ?? filter.name}\n <select\n className={controlClasses()}\n value={value === undefined || value === null ? '' : String(value)}\n onChange={(e) => onChange(e.target.value === '' ? null : e.target.value)}\n >\n <option value=\"\">{t('table.filters.all', 'All')}</option>\n {filter.props.options.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n );\n}\n\nfunction MultiSelectFilter({\n filter,\n value,\n onChange,\n}: {\n filter: MultiSelectFilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const arr = Array.isArray(value) ? (value as Array<string | number>) : [];\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {filter.label ?? filter.name}\n <select\n multiple\n className={cn(controlClasses(), 'h-auto min-h-11 py-1 md:min-h-[2.25rem]')}\n value={arr.map(String)}\n onChange={(e) => {\n const next = Array.from(e.target.selectedOptions, (o) => o.value);\n onChange(next.length === 0 ? null : next);\n }}\n >\n {filter.props.options.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </label>\n );\n}\n\nfunction TextFilter({\n filter,\n value,\n onChange,\n}: {\n filter: TextFilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {filter.label ?? filter.name}\n <input\n type=\"text\"\n className={controlClasses()}\n value={typeof value === 'string' ? value : ''}\n onChange={(e) => onChange(e.target.value === '' ? null : e.target.value)}\n />\n </label>\n );\n}\n\nfunction TernaryFilter({\n filter,\n value,\n onChange,\n}: {\n filter: TernaryFilterSchema;\n value: unknown;\n onChange: (value: unknown) => void;\n}) {\n const t = useArqelTranslations();\n const current = value === undefined || value === null ? 'all' : String(value);\n return (\n <label className=\"flex flex-col gap-1 text-xs text-muted-foreground\">\n {filter.label ?? filter.name}\n <select\n className={controlClasses()}\n value={current}\n onChange={(e) => {\n const v = e.target.value;\n onChange(v === 'all' ? null : v);\n }}\n >\n <option value=\"all\">{filter.props.allLabel ?? t('table.filters.all', 'All')}</option>\n <option value=\"true\">{filter.props.trueLabel ?? 'Yes'}</option>\n <option value=\"false\">{filter.props.falseLabel ?? 'No'}</option>\n </select>\n </label>\n );\n}\n","/**\n * `<TablePagination>` — prev/next + range + per-page picker.\n *\n * Stateless: parent owns `currentPage` / `perPage` and handles transitions\n * (typically via Inertia `router.get` with `preserveState: true`).\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { PaginationMeta } from '@arqel-dev/types/resources';\nimport { Button } from '../action/Button.js';\nimport { cn } from '../utils/cn.js';\n\nexport interface TablePaginationProps {\n meta: PaginationMeta;\n onPageChange: (page: number) => void;\n onPerPageChange?: ((perPage: number) => void) | undefined;\n perPageOptions?: number[];\n className?: string;\n}\n\nexport function TablePagination({\n meta,\n onPageChange,\n onPerPageChange,\n perPageOptions = [10, 25, 50, 100],\n className,\n}: TablePaginationProps) {\n const t = useArqelTranslations();\n const from = (meta.currentPage - 1) * meta.perPage + 1;\n const to = Math.min(meta.currentPage * meta.perPage, meta.total);\n const isFirst = meta.currentPage <= 1;\n const isLast = meta.currentPage >= meta.lastPage;\n\n return (\n <nav\n className={cn(\n 'flex flex-wrap items-center justify-between gap-2 border-t border-border px-3 py-2 text-sm',\n className,\n )}\n aria-label=\"Pagination\"\n >\n <span className=\"text-muted-foreground\">\n {meta.total === 0 ? t('table.empty', 'No results') : `${from}–${to} of ${meta.total}`}\n </span>\n <div className=\"flex items-center gap-2\">\n {onPerPageChange && (\n <label className=\"flex items-center gap-1 text-xs text-muted-foreground\">\n {t('table.per_page', 'Per page')}\n {/* 44px touch target on mobile (WCAG 2.5.5); dense 32px on >=md. */}\n <select\n className=\"h-11 rounded-sm border border-[var(--input)] bg-background px-2 md:h-8\"\n value={meta.perPage}\n onChange={(e) => onPerPageChange(Number(e.target.value))}\n >\n {perPageOptions.map((n) => (\n <option key={n} value={n}>\n {n}\n </option>\n ))}\n </select>\n </label>\n )}\n {/* Buttons use size=\"sm\" (h-8) for the dense desktop bar; the responsive\n h-11 override lifts them to a 44px touch target below md. */}\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-11 md:h-8\"\n disabled={isFirst}\n onClick={() => onPageChange(meta.currentPage - 1)}\n aria-label={t('table.pagination.previous_page', 'Previous page')}\n >\n {t('table.pagination.previous', 'Prev')}\n </Button>\n <span className=\"text-xs text-muted-foreground\">\n {meta.currentPage} / {meta.lastPage}\n </span>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-11 md:h-8\"\n disabled={isLast}\n onClick={() => onPageChange(meta.currentPage + 1)}\n aria-label={t('table.pagination.next_page', 'Next page')}\n >\n {t('table.pagination.next', 'Next')}\n </Button>\n </div>\n </nav>\n );\n}\n","/**\n * `<TableToolbar>` — search input + filters + bulk-action bar slot.\n *\n * The bulk-action bar appears only when `selectedCount > 0`. ResourceIndex\n * passes `bulkActions` rendered as a row of buttons; the toolbar just\n * positions them.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface TableToolbarProps {\n search?: ReactNode;\n filters?: ReactNode;\n selectedCount?: number;\n bulkActions?: ReactNode;\n onClearSelection?: (() => void) | undefined;\n className?: string;\n}\n\nexport function TableToolbar({\n search,\n filters,\n selectedCount = 0,\n bulkActions,\n onClearSelection,\n className,\n}: TableToolbarProps) {\n const t = useArqelTranslations();\n return (\n <div className={cn('flex flex-col gap-3 px-3 py-3', className)}>\n <div className=\"flex flex-wrap items-end gap-2\">\n {search}\n {filters}\n </div>\n {selectedCount > 0 && (\n <section\n className=\"flex flex-wrap items-center gap-2 rounded-sm border border-border bg-muted px-3 py-2\"\n aria-label=\"Bulk actions\"\n >\n <span className=\"text-sm font-medium\">\n {t('table.bulk.selected', `${selectedCount} selected`, { count: selectedCount })}\n </span>\n <div className=\"ml-auto flex flex-wrap items-center gap-2\">\n {bulkActions}\n {onClearSelection && (\n <button\n type=\"button\"\n className=\"text-sm text-muted-foreground hover:underline\"\n onClick={onClearSelection}\n >\n {t('table.bulk.clear', 'Clear')}\n </button>\n )}\n </div>\n </section>\n )}\n </div>\n );\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { DashboardGrid } from './chunk-47HD7ALI.js';
1
+ import { DashboardGrid } from './chunk-HSDZM4AM.js';
2
2
  import { usePage, router } from '@inertiajs/react';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
@@ -31,5 +31,5 @@ function ArqelDashboardPage() {
31
31
  }
32
32
 
33
33
  export { ArqelDashboardPage };
34
- //# sourceMappingURL=chunk-PXON56HL.js.map
35
- //# sourceMappingURL=chunk-PXON56HL.js.map
34
+ //# sourceMappingURL=chunk-BJER6TOI.js.map
35
+ //# sourceMappingURL=chunk-BJER6TOI.js.map