@arqel-dev/ui 0.14.0 → 0.15.1

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 (108) hide show
  1. package/README.md +1 -1
  2. package/dist/{AreaChart-NMQ2RQGA.js → AreaChart-JAZ6LUYG.js} +8 -4
  3. package/dist/AreaChart-JAZ6LUYG.js.map +1 -0
  4. package/dist/ArqelCreatePage-UZAHV4DK.js +8 -0
  5. package/dist/{ArqelCreatePage-O6KNXPAO.js.map → ArqelCreatePage-UZAHV4DK.js.map} +1 -1
  6. package/dist/ArqelDashboardPage-Z5R4XSH4.js +6 -0
  7. package/dist/{ArqelDashboardPage-PX3Y75AA.js.map → ArqelDashboardPage-Z5R4XSH4.js.map} +1 -1
  8. package/dist/ArqelEditPage-RRYFYOTC.js +8 -0
  9. package/dist/{ArqelShowPage-LGVTL6UZ.js.map → ArqelEditPage-RRYFYOTC.js.map} +1 -1
  10. package/dist/ArqelIndexPage-RGZWKKAX.js +12 -0
  11. package/dist/{ArqelIndexPage-GC33PNBL.js.map → ArqelIndexPage-RGZWKKAX.js.map} +1 -1
  12. package/dist/ArqelShowPage-TVCJAV2F.js +6 -0
  13. package/dist/{ArqelEditPage-NAMWJ5MC.js.map → ArqelShowPage-TVCJAV2F.js.map} +1 -1
  14. package/dist/{BarChart-KLHKTLO2.js → BarChart-E52NJSJE.js} +8 -4
  15. package/dist/BarChart-E52NJSJE.js.map +1 -0
  16. package/dist/{DonutChart-L56R4QF2.js → DonutChart-IGSF4LEB.js} +3 -3
  17. package/dist/{DonutChart-L56R4QF2.js.map → DonutChart-IGSF4LEB.js.map} +1 -1
  18. package/dist/{FormRenderer-BJBRIkfH.d.ts → FormRenderer-By8fZp4t.d.ts} +2 -0
  19. package/dist/{LineChart-GHMPHFZZ.js → LineChart-RRPGAZON.js} +8 -4
  20. package/dist/LineChart-RRPGAZON.js.map +1 -0
  21. package/dist/PieChart-SGN7V5LQ.js +4 -0
  22. package/dist/{PieChart-T2VQOFPP.js.map → PieChart-SGN7V5LQ.js.map} +1 -1
  23. package/dist/{RadarChart-CSWR5AO7.js → RadarChart-3AOM736J.js} +8 -4
  24. package/dist/RadarChart-3AOM736J.js.map +1 -0
  25. package/dist/action.d.ts +1 -1
  26. package/dist/action.js +5 -5
  27. package/dist/{chunk-IKJYLSTK.js → chunk-2JUWLJ3K.js} +90 -29
  28. package/dist/chunk-2JUWLJ3K.js.map +1 -0
  29. package/dist/chunk-3HN4ARGG.js +157 -0
  30. package/dist/chunk-3HN4ARGG.js.map +1 -0
  31. package/dist/{chunk-PXON56HL.js → chunk-3VSDQCFO.js} +3 -3
  32. package/dist/{chunk-PXON56HL.js.map → chunk-3VSDQCFO.js.map} +1 -1
  33. package/dist/{chunk-6UJQP7KU.js → chunk-4VWNBMMA.js} +34 -118
  34. package/dist/chunk-4VWNBMMA.js.map +1 -0
  35. package/dist/{chunk-4JJS2SVS.js → chunk-CMNZLA32.js} +83 -32
  36. package/dist/chunk-CMNZLA32.js.map +1 -0
  37. package/dist/{chunk-2LTZJ4R7.js → chunk-EG2DASKR.js} +16 -7
  38. package/dist/chunk-EG2DASKR.js.map +1 -0
  39. package/dist/{chunk-DSULVRB6.js → chunk-GJ2FKAOM.js} +5 -3
  40. package/dist/chunk-GJ2FKAOM.js.map +1 -0
  41. package/dist/{chunk-FHRQ7PWE.js → chunk-H23VX3RR.js} +4 -3
  42. package/dist/chunk-H23VX3RR.js.map +1 -0
  43. package/dist/{chunk-FV7RESKL.js → chunk-HNUUZEOL.js} +28 -16
  44. package/dist/chunk-HNUUZEOL.js.map +1 -0
  45. package/dist/{chunk-M6NI45DQ.js → chunk-IO6RMVUF.js} +9 -5
  46. package/dist/chunk-IO6RMVUF.js.map +1 -0
  47. package/dist/{chunk-I6MWOIFR.js → chunk-LLANMODS.js} +6 -5
  48. package/dist/chunk-LLANMODS.js.map +1 -0
  49. package/dist/{chunk-MTZJDFQ6.js → chunk-MZMYV43C.js} +11 -7
  50. package/dist/chunk-MZMYV43C.js.map +1 -0
  51. package/dist/{chunk-E2ORVQM5.js → chunk-Q7WGPKUN.js} +6 -4
  52. package/dist/chunk-Q7WGPKUN.js.map +1 -0
  53. package/dist/{chunk-PZEVKMZX.js → chunk-S5UNPCMQ.js} +315 -152
  54. package/dist/chunk-S5UNPCMQ.js.map +1 -0
  55. package/dist/{chunk-MTNFFSVA.js → chunk-SK6H7ARE.js} +5 -3
  56. package/dist/chunk-SK6H7ARE.js.map +1 -0
  57. package/dist/{chunk-WKWV36PG.js → chunk-WMOBLT3Z.js} +12 -5
  58. package/dist/chunk-WMOBLT3Z.js.map +1 -0
  59. package/dist/{chunk-C5H44NSP.js → chunk-WZRPGPLH.js} +10 -5
  60. package/dist/chunk-WZRPGPLH.js.map +1 -0
  61. package/dist/{chunk-QTUBBZVT.js → chunk-YQ6KXR3U.js} +9 -11
  62. package/dist/chunk-YQ6KXR3U.js.map +1 -0
  63. package/dist/{chunk-47HD7ALI.js → chunk-YYQ45W25.js} +37 -24
  64. package/dist/chunk-YYQ45W25.js.map +1 -0
  65. package/dist/flash.js +1 -1
  66. package/dist/form.d.ts +3 -1
  67. package/dist/form.js +3 -3
  68. package/dist/index.d.ts +1 -1
  69. package/dist/index.js +12 -12
  70. package/dist/pages.js +19 -19
  71. package/dist/palette.js +1 -1
  72. package/dist/resource.js +3 -3
  73. package/dist/shell.js +10 -6
  74. package/dist/shell.js.map +1 -1
  75. package/dist/table.js +2 -2
  76. package/dist/utility.js +1 -1
  77. package/dist/widgets.js +2 -2
  78. package/package.json +6 -6
  79. package/src/styles/globals.css +7 -0
  80. package/dist/AreaChart-NMQ2RQGA.js.map +0 -1
  81. package/dist/ArqelCreatePage-O6KNXPAO.js +0 -8
  82. package/dist/ArqelDashboardPage-PX3Y75AA.js +0 -6
  83. package/dist/ArqelEditPage-NAMWJ5MC.js +0 -8
  84. package/dist/ArqelIndexPage-GC33PNBL.js +0 -12
  85. package/dist/ArqelShowPage-LGVTL6UZ.js +0 -6
  86. package/dist/BarChart-KLHKTLO2.js.map +0 -1
  87. package/dist/LineChart-GHMPHFZZ.js.map +0 -1
  88. package/dist/PieChart-T2VQOFPP.js +0 -4
  89. package/dist/RadarChart-CSWR5AO7.js.map +0 -1
  90. package/dist/chunk-2LTZJ4R7.js.map +0 -1
  91. package/dist/chunk-47HD7ALI.js.map +0 -1
  92. package/dist/chunk-4JJS2SVS.js.map +0 -1
  93. package/dist/chunk-6UJQP7KU.js.map +0 -1
  94. package/dist/chunk-C5H44NSP.js.map +0 -1
  95. package/dist/chunk-DSULVRB6.js.map +0 -1
  96. package/dist/chunk-E2ORVQM5.js.map +0 -1
  97. package/dist/chunk-EYAUPJ6J.js +0 -64
  98. package/dist/chunk-EYAUPJ6J.js.map +0 -1
  99. package/dist/chunk-FHRQ7PWE.js.map +0 -1
  100. package/dist/chunk-FV7RESKL.js.map +0 -1
  101. package/dist/chunk-I6MWOIFR.js.map +0 -1
  102. package/dist/chunk-IKJYLSTK.js.map +0 -1
  103. package/dist/chunk-M6NI45DQ.js.map +0 -1
  104. package/dist/chunk-MTNFFSVA.js.map +0 -1
  105. package/dist/chunk-MTZJDFQ6.js.map +0 -1
  106. package/dist/chunk-PZEVKMZX.js.map +0 -1
  107. package/dist/chunk-QTUBBZVT.js.map +0 -1
  108. package/dist/chunk-WKWV36PG.js.map +0 -1
@@ -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":["useArqelTranslations","jsx","jsxs","useArqelLocale","useMemo"],"mappings":"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","file":"chunk-S5UNPCMQ.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 { useArqelLocale, useArqelTranslations } from '@arqel-dev/react/utils';\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 t = useArqelTranslations();\n const truthy = Boolean(value);\n // The glyph stays language-neutral; only the screen-reader accessible name is\n // localized so a pt-BR viewer hears \"sim\"/\"não\" instead of \"true\"/\"false\".\n const ariaLabel = truthy\n ? t('table.boolean.true_label', 'true')\n : t('table.boolean.false_label', 'false');\n return (\n <span role=\"img\" aria-label={ariaLabel}>\n {truthy ? (column.props.trueIcon ?? '✓') : (column.props.falseIcon ?? '—')}\n </span>\n );\n}\n\nfunction DateCell({ column, value }: { column: DateColumnSchema; value: unknown }) {\n // Active panel locale (BCP-47), so dates format in the viewer's locale rather\n // than the runtime default (commonly en-US 'MM/DD/YYYY').\n const locale = useArqelLocale();\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 // `timezone` is honoured when the server emits it; an invalid zone would make\n // `Intl` throw, so fall back to the runtime zone defensively.\n const timeZone = column.props.timezone || undefined;\n if (column.props.mode === 'since') {\n return <time dateTime={date.toISOString()}>{formatRelative(date, locale)}</time>;\n }\n if (column.props.mode === 'datetime') {\n return (\n <time dateTime={date.toISOString()}>{formatDate(date, locale, 'datetime', timeZone)}</time>\n );\n }\n return <time dateTime={date.toISOString()}>{formatDate(date, locale, 'date', timeZone)}</time>;\n}\n\nfunction formatDate(\n date: Date,\n locale: string,\n mode: 'date' | 'datetime',\n timeZone: string | undefined,\n): string {\n const options: Intl.DateTimeFormatOptions =\n mode === 'datetime' ? { dateStyle: 'medium', timeStyle: 'short' } : { dateStyle: 'medium' };\n if (timeZone !== undefined) options.timeZone = timeZone;\n try {\n return new Intl.DateTimeFormat(locale, options).format(date);\n } catch {\n // Invalid timezone (or other Intl error) — retry without it.\n if (timeZone !== undefined) {\n const { timeZone: _drop, ...rest } = options;\n return new Intl.DateTimeFormat(locale, rest).format(date);\n }\n return mode === 'datetime' ? date.toISOString() : date.toISOString().slice(0, 10);\n }\n}\n\nfunction formatRelative(date: Date, locale: string): string {\n const seconds = Math.round((Date.now() - date.getTime()) / 1000);\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n // Negative values render as \"X ago\"; the elapsed time is always in the past.\n const absSeconds = Math.abs(seconds);\n if (absSeconds < 60) return rtf.format(-seconds, 'second');\n const minutes = Math.round(seconds / 60);\n if (Math.abs(minutes) < 60) return rtf.format(-minutes, 'minute');\n const hours = Math.round(minutes / 60);\n if (Math.abs(hours) < 24) return rtf.format(-hours, 'hour');\n const days = Math.round(hours / 24);\n return rtf.format(-days, 'day');\n}\n\nfunction NumberCell({ column, value }: { column: NumberColumnSchema; value: unknown }) {\n const locale = useArqelLocale();\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\n // `money($currency)` → render through `Intl.NumberFormat` in the active locale\n // so the currency symbol, grouping and decimals follow the viewer's panel.\n if (column.props.currency) {\n try {\n const formatted = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: column.props.currency,\n ...(column.props.decimals !== undefined\n ? {\n minimumFractionDigits: column.props.decimals,\n maximumFractionDigits: column.props.decimals,\n }\n : {}),\n }).format(num);\n return (\n <span>\n {column.props.prefix ?? ''}\n {formatted}\n {column.props.suffix ?? ''}\n </span>\n );\n } catch {\n // Unknown currency code — fall through to the plain numeric path below.\n }\n }\n\n const decimals = column.props.decimals ?? 0;\n // Explicit separators win (developer override). Otherwise group/decimal in the\n // active locale via Intl instead of the previous en-US-shaped raw output.\n const ts = column.props.thousandsSeparator;\n const ds = column.props.decimalSeparator;\n let body: string;\n if (ts === undefined && ds === undefined) {\n body = new Intl.NumberFormat(locale, {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n }).format(num);\n } else {\n const formatted = num.toFixed(decimals);\n const [whole, dec] = formatted.split('.');\n const safeWhole = whole ?? '0';\n const finalWhole = ts ? safeWhole.replace(/\\B(?=(\\d{3})+(?!\\d))/g, ts) : safeWhole;\n body = dec ? `${finalWhole}${ds ?? '.'}${dec}` : finalWhole;\n }\n return (\n <span>\n {column.props.prefix ?? ''}\n {body}\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 { useArqelTranslations } from '@arqel-dev/react/utils';\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 t = useArqelTranslations();\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={t('table.bulk.select_all_rows', '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\n scope=\"col\"\n className=\"w-24 px-3 py-2 text-right\"\n aria-label={t('table.column.actions', 'Actions')}\n />\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 {t('table.loading', '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 ?? t('table.empty', '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={t('table.bulk.select_row', `Select row ${record.id}`, {\n id: String(record.id),\n })}\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 const t = useArqelTranslations();\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 (\n <div className=\"px-3 py-4 text-center text-muted-foreground md:hidden\">\n {t('table.loading', 'Loading…')}\n </div>\n );\n }\n if (rows.length === 0) {\n return (\n <div className=\"px-3 py-8 text-center text-muted-foreground md:hidden\">\n {emptyState ?? t('table.empty', '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={t('table.bulk.select_row', `Select row ${record.id}`, {\n id: String(record.id),\n })}\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\">{t('table.filters.legend', '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 ?? t('table.filters.yes', 'Yes')}</option>\n <option value=\"false\">{filter.props.falseLabel ?? t('table.filters.no', '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 { useArqelLocale, useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { PaginationMeta } from '@arqel-dev/types/resources';\nimport { useMemo } from 'react';\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 locale = useArqelLocale();\n const numberFormatter = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n const fromRaw = (meta.currentPage - 1) * meta.perPage + 1;\n const toRaw = Math.min(meta.currentPage * meta.perPage, meta.total);\n // Interpolated counts are locale number-grouped (12,345 / 12.345) before they\n // reach the translator, whose applyReplacements does plain String() substitution.\n const from = numberFormatter.format(fromRaw);\n const to = numberFormatter.format(toRaw);\n const total = numberFormatter.format(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={t('table.pagination.label', 'Pagination')}\n >\n <span className=\"text-muted-foreground\">\n {meta.total === 0\n ? t('table.empty', 'No records found.')\n : t(\n 'table.pagination.showing',\n // Fallback is rendered verbatim when the key is missing, so it must\n // already carry the interpolated values (the replacements map only\n // applies to a resolved dictionary string).\n `Showing ${from} to ${to} of ${total} results`,\n { from, to, total },\n )}\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 {numberFormatter.format(meta.currentPage)} / {numberFormatter.format(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={t('table.bulk.label', 'Bulk actions')}\n >\n <span className=\"text-sm font-medium\">\n {t('table.bulk.selected', '{one} :count selected|{other} :count selected', {\n count: selectedCount,\n })}\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,5 @@
1
1
  import { cn } from './chunk-B7ULUJVO.js';
2
+ import { useArqelTranslations } from '@arqel-dev/react/utils';
2
3
  import { usePage } from '@inertiajs/react';
3
4
  import { jsx, jsxs } from 'react/jsx-runtime';
4
5
 
@@ -18,8 +19,9 @@ function BreadcrumbsList({
18
19
  separator = /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "/" }),
19
20
  className
20
21
  }) {
22
+ const t = useArqelTranslations();
21
23
  if (items.length === 0) return null;
22
- return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: cn("text-sm", className), children: /* @__PURE__ */ jsx("ol", { className: "flex flex-wrap items-center gap-2 text-muted-foreground", children: items.map((item, index) => {
24
+ return /* @__PURE__ */ jsx("nav", { "aria-label": t("arqel.aria.breadcrumb", "Breadcrumb"), className: cn("text-sm", className), children: /* @__PURE__ */ jsx("ol", { className: "flex flex-wrap items-center gap-2 text-muted-foreground", children: items.map((item, index) => {
23
25
  const isLast = index === items.length - 1;
24
26
  return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-2", children: [
25
27
  isLast || !item.url ? /* @__PURE__ */ jsx("span", { "aria-current": isLast ? "page" : void 0, className: "text-foreground", children: item.label }) : /* @__PURE__ */ jsx("a", { href: item.url, className: "hover:underline", children: item.label }),
@@ -88,5 +90,5 @@ function LoadingSkeleton({
88
90
  }
89
91
 
90
92
  export { Breadcrumbs, EmptyState, ErrorState, LoadingSkeleton };
91
- //# sourceMappingURL=chunk-MTNFFSVA.js.map
92
- //# sourceMappingURL=chunk-MTNFFSVA.js.map
93
+ //# sourceMappingURL=chunk-SK6H7ARE.js.map
94
+ //# sourceMappingURL=chunk-SK6H7ARE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utility/Breadcrumbs.tsx","../src/utility/EmptyState.tsx","../src/utility/ErrorState.tsx","../src/utility/LoadingSkeleton.tsx"],"names":["jsxs","jsx"],"mappings":"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","file":"chunk-SK6H7ARE.js","sourcesContent":["/**\n * `<Breadcrumbs>` — renders the panel's breadcrumb trail.\n *\n * Items can be passed explicitly, or auto-resolved from Inertia shared\n * props (`panel.breadcrumbs`, populated server-side by\n * `Arqel\\Nav\\BreadcrumbsBuilder`). Each item is a link unless it's the\n * last entry, which is rendered as plain text and marked\n * `aria-current=\"page\"`.\n *\n * `usePage()` is only invoked when `items` is omitted — explicit-items\n * usage works outside Inertia (e.g. dashboard widgets, tests).\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport { usePage } from '@inertiajs/react';\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface BreadcrumbItem {\n label: string;\n url?: string | null;\n}\n\nexport interface BreadcrumbsProps {\n items?: BreadcrumbItem[];\n separator?: ReactNode;\n className?: string;\n}\n\ninterface PanelWithCrumbs {\n panel?: { breadcrumbs?: BreadcrumbItem[] } | null;\n}\n\nexport function Breadcrumbs(props: BreadcrumbsProps) {\n if (props.items === undefined) {\n return <SharedBreadcrumbs {...props} />;\n }\n return <BreadcrumbsList {...props} items={props.items} />;\n}\n\nfunction SharedBreadcrumbs(props: BreadcrumbsProps) {\n const page = usePage();\n const items = (page.props as unknown as PanelWithCrumbs).panel?.breadcrumbs ?? [];\n return <BreadcrumbsList {...props} items={items} />;\n}\n\nfunction BreadcrumbsList({\n items,\n separator = <span aria-hidden=\"true\">/</span>,\n className,\n}: BreadcrumbsProps & { items: BreadcrumbItem[] }) {\n const t = useArqelTranslations();\n if (items.length === 0) return null;\n\n return (\n <nav aria-label={t('arqel.aria.breadcrumb', 'Breadcrumb')} className={cn('text-sm', className)}>\n <ol className=\"flex flex-wrap items-center gap-2 text-muted-foreground\">\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n return (\n <li key={`${item.label}-${item.url ?? 'leaf'}`} className=\"flex items-center gap-2\">\n {isLast || !item.url ? (\n <span aria-current={isLast ? 'page' : undefined} className=\"text-foreground\">\n {item.label}\n </span>\n ) : (\n <a href={item.url} className=\"hover:underline\">\n {item.label}\n </a>\n )}\n {!isLast && separator}\n </li>\n );\n })}\n </ol>\n </nav>\n );\n}\n","/**\n * `<EmptyState>` — standardised empty-state block.\n *\n * Used by DataTable's empty slot and as a stand-alone fallback when\n * a resource collection has zero records.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface EmptyStateProps {\n title: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n action?: ReactNode;\n className?: string;\n}\n\nexport function EmptyState({ title, description, icon, action, className }: EmptyStateProps) {\n return (\n <div\n className={cn(\n 'flex flex-col items-center gap-3 px-4 py-12 text-center text-muted-foreground',\n className,\n )}\n >\n {icon && <div className=\"text-3xl\">{icon}</div>}\n <h2 className=\"text-base font-semibold text-foreground\">{title}</h2>\n {description && <p className=\"max-w-md text-sm\">{description}</p>}\n {action && <div className=\"mt-2\">{action}</div>}\n </div>\n );\n}\n","/**\n * `<ErrorState>` — generic error block (404 / 403 / 500).\n *\n * Phase 1 ships a plain layout; richer illustrations / Heroicons land\n * with `@arqel-dev/fields` icon registry.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface ErrorStateProps {\n status?: number;\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n className?: string;\n}\n\nexport function ErrorState({ status, title, description, action, className }: ErrorStateProps) {\n return (\n <div\n role=\"alert\"\n className={cn('flex flex-col items-center gap-3 px-4 py-16 text-center', className)}\n >\n {status && <span className=\"text-sm font-mono text-muted-foreground\">{status}</span>}\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n {description && <p className=\"max-w-md text-sm text-muted-foreground\">{description}</p>}\n {action && <div className=\"mt-2\">{action}</div>}\n </div>\n );\n}\n","/**\n * `<LoadingSkeleton>` — animated placeholder block.\n *\n * Variants:\n * - `line`: single text line (default)\n * - `block`: rectangular block (cards, hero areas)\n * - `circle`: circular (avatars)\n *\n * Heights / widths default to readable values; override via Tailwind\n * classes or explicit `height` / `width` props for bespoke layouts.\n */\n\nimport { cn } from '../utils/cn.js';\n\nexport type SkeletonVariant = 'line' | 'block' | 'circle';\n\nexport interface LoadingSkeletonProps {\n variant?: SkeletonVariant;\n width?: number | string;\n height?: number | string;\n count?: number;\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<SkeletonVariant, string> = {\n line: 'h-4 w-full',\n block: 'h-24 w-full',\n circle: 'h-10 w-10 rounded-full',\n};\n\nexport function LoadingSkeleton({\n variant = 'line',\n width,\n height,\n count = 1,\n className,\n}: LoadingSkeletonProps) {\n const items = Array.from({ length: count }, (_, i) => i);\n return (\n <div className=\"flex flex-col gap-2\" aria-hidden=\"true\">\n {items.map((i) => (\n <div\n key={i}\n style={{ width, height }}\n className={cn(\n 'animate-pulse bg-muted',\n variant !== 'circle' && 'rounded-sm',\n VARIANT_CLASSES[variant],\n className,\n )}\n />\n ))}\n </div>\n );\n}\n"]}
@@ -1,5 +1,7 @@
1
1
  import { cn } from './chunk-B7ULUJVO.js';
2
+ import { useArqelTranslations, useArqelLocale } from '@arqel-dev/react/utils';
2
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
+ import { useMemo } from 'react';
3
5
 
4
6
  function resolveColumnSpan(columnSpan) {
5
7
  if (columnSpan === void 0) return void 0;
@@ -16,6 +18,7 @@ function WidgetWrapper({
16
18
  className,
17
19
  children
18
20
  }) {
21
+ const t = useArqelTranslations();
19
22
  const baseClass = cn(
20
23
  "rounded border bg-background p-4",
21
24
  resolveColumnSpan(columnSpan),
@@ -42,7 +45,7 @@ function WidgetWrapper({
42
45
  type: "button",
43
46
  onClick: onRetry,
44
47
  className: "self-start rounded border px-2 py-1 text-xs text-foreground hover:bg-muted",
45
- children: "Retry"
48
+ children: t("arqel.actions.retry", "Retry")
46
49
  }
47
50
  )
48
51
  ] }) });
@@ -70,6 +73,7 @@ var COLOR_STROKE = {
70
73
  info: "stroke-sky-500"
71
74
  };
72
75
  function Sparkline({ points, color }) {
76
+ const t = useArqelTranslations();
73
77
  if (points.length < 2) return null;
74
78
  const min = Math.min(...points);
75
79
  const max = Math.max(...points);
@@ -87,7 +91,7 @@ function Sparkline({ points, color }) {
87
91
  preserveAspectRatio: "none",
88
92
  className: cn("mt-3 h-8 w-full", COLOR_STROKE[color]),
89
93
  role: "img",
90
- "aria-label": "Trend sparkline",
94
+ "aria-label": t("arqel.aria.stat_sparkline", "Trend sparkline"),
91
95
  "data-testid": "stat-card-sparkline",
92
96
  children: /* @__PURE__ */ jsx(
93
97
  "polyline",
@@ -105,9 +109,12 @@ function Sparkline({ points, color }) {
105
109
  }
106
110
  function StatCard({ widget, className, columnSpan }) {
107
111
  const { heading, description, value, statDescription, descriptionIcon, color, chart, url } = widget;
112
+ const locale = useArqelLocale();
113
+ const numberFormatter = useMemo(() => new Intl.NumberFormat(locale), [locale]);
114
+ const displayValue = typeof value === "number" && Number.isFinite(value) ? numberFormatter.format(value) : value ?? "\u2014";
108
115
  const hasChart = Array.isArray(chart) && chart.length >= 2;
109
116
  const body = /* @__PURE__ */ jsxs(Fragment, { children: [
110
- /* @__PURE__ */ jsx("div", { className: cn("text-4xl font-bold tabular-nums", COLOR_TEXT[color]), children: value ?? "\u2014" }),
117
+ /* @__PURE__ */ jsx("div", { className: cn("text-4xl font-bold tabular-nums", COLOR_TEXT[color]), children: displayValue }),
111
118
  statDescription && /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-1 text-xs text-muted-foreground", children: [
112
119
  descriptionIcon && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", "data-testid": "stat-card-icon", children: descriptionIcon }),
113
120
  /* @__PURE__ */ jsx("span", { children: statDescription })
@@ -136,5 +143,5 @@ function StatCard({ widget, className, columnSpan }) {
136
143
  }
137
144
 
138
145
  export { StatCard, WidgetWrapper };
139
- //# sourceMappingURL=chunk-WKWV36PG.js.map
140
- //# sourceMappingURL=chunk-WKWV36PG.js.map
146
+ //# sourceMappingURL=chunk-WMOBLT3Z.js.map
147
+ //# sourceMappingURL=chunk-WMOBLT3Z.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/widgets/WidgetWrapper.tsx","../src/widgets/StatCard.tsx"],"names":["useArqelTranslations","jsx","jsxs"],"mappings":"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","file":"chunk-WMOBLT3Z.js","sourcesContent":["/**\n * `<WidgetWrapper>` — common chrome for dashboard widgets.\n *\n * Provides:\n * - Heading / description header.\n * - Loading skeleton (CLS-safe placeholder while deferred widgets fetch).\n * - Error state (`role=\"alert\"`) with optional retry action.\n * - `aria-label`-ed `<section>` so widgets are individually navigable.\n *\n * Used by `<StatCard>` (and shortly `<ChartCard>` / `<TableCard>`) so the\n * outer card chrome is consistent across widget types.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface WidgetWrapperProps {\n heading?: string | undefined;\n description?: string | undefined;\n loading?: boolean | undefined;\n error?: Error | null | undefined;\n onRetry?: (() => void) | undefined;\n /** Tailwind grid column span (number → `col-span-{n}`, or raw class). */\n columnSpan?: number | string | undefined;\n className?: string | undefined;\n children: ReactNode;\n}\n\nfunction resolveColumnSpan(columnSpan?: number | string): string | undefined {\n if (columnSpan === undefined) return undefined;\n if (typeof columnSpan === 'number') return `col-span-${columnSpan}`;\n return columnSpan;\n}\n\nexport function WidgetWrapper({\n heading,\n description,\n loading = false,\n error = null,\n onRetry,\n columnSpan,\n className,\n children,\n}: WidgetWrapperProps) {\n const t = useArqelTranslations();\n const baseClass = cn(\n 'rounded border bg-background p-4',\n resolveColumnSpan(columnSpan),\n className,\n );\n\n if (loading) {\n return (\n <section\n aria-label={heading}\n aria-busy=\"true\"\n className={baseClass}\n data-widget-state=\"loading\"\n >\n <div className=\"animate-pulse h-32 bg-muted rounded\" />\n </section>\n );\n }\n\n if (error) {\n return (\n <section aria-label={heading} className={baseClass} data-widget-state=\"error\">\n <div role=\"alert\" className=\"flex flex-col gap-2 text-sm text-destructive\">\n <p>{error.message}</p>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"self-start rounded border px-2 py-1 text-xs text-foreground hover:bg-muted\"\n >\n {t('arqel.actions.retry', 'Retry')}\n </button>\n )}\n </div>\n </section>\n );\n }\n\n return (\n <section aria-label={heading} className={baseClass} data-widget-state=\"ready\">\n {heading && <h2 className=\"text-sm font-medium text-muted-foreground\">{heading}</h2>}\n {description && <p className=\"mt-1 text-xs text-muted-foreground\">{description}</p>}\n <div className={cn(heading || description ? 'mt-3' : undefined)}>{children}</div>\n </section>\n );\n}\n","/**\n * `<StatCard>` — KPI / \"big number\" widget.\n *\n * Renders the payload produced by `Arqel\\Widgets\\StatWidget::data()`:\n *\n * {\n * name, type: 'stat', heading?, description?,\n * value, statDescription?, descriptionIcon?,\n * color, icon?, chart?: number[], url?\n * }\n *\n * Includes a tiny inline-SVG sparkline (no Recharts dep) when `chart`\n * is set. ChartCard / TableCard (Recharts-based) ship in a separate\n * cluster; this component is intentionally Recharts-free so the\n * common \"big number\" case stays bundle-cheap.\n */\n\nimport { useArqelLocale, useArqelTranslations } from '@arqel-dev/react/utils';\nimport { type ReactNode, useMemo } from 'react';\nimport { cn } from '../utils/cn.js';\nimport { WidgetWrapper } from './WidgetWrapper.js';\n\nexport type StatCardColor = 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface StatCardWidget {\n name: string;\n type: 'stat';\n heading?: string;\n description?: string;\n value: string | number | null;\n statDescription?: string | null;\n descriptionIcon?: string | null;\n color: StatCardColor;\n icon?: string | null;\n chart?: number[] | null;\n url?: string | null;\n}\n\nexport interface StatCardProps {\n widget: StatCardWidget;\n className?: string | undefined;\n columnSpan?: number | string | undefined;\n}\n\nconst COLOR_TEXT: Record<StatCardColor, string> = {\n primary: 'text-primary',\n secondary: 'text-secondary-foreground',\n success: 'text-green-600',\n warning: 'text-amber-600',\n danger: 'text-red-600',\n info: 'text-sky-600',\n};\n\nconst COLOR_STROKE: Record<StatCardColor, string> = {\n primary: 'stroke-primary',\n secondary: 'stroke-secondary-foreground',\n success: 'stroke-green-500',\n warning: 'stroke-amber-500',\n danger: 'stroke-red-500',\n info: 'stroke-sky-500',\n};\n\ninterface SparklineProps {\n points: number[];\n color: StatCardColor;\n}\n\nfunction Sparkline({ points, color }: SparklineProps) {\n const t = useArqelTranslations();\n if (points.length < 2) return null;\n\n const min = Math.min(...points);\n const max = Math.max(...points);\n const range = max - min || 1;\n const stepX = 100 / (points.length - 1);\n\n const coords = points\n .map((value, index) => {\n const x = index * stepX;\n // Invert Y so larger values render higher in the viewBox.\n const y = 30 - ((value - min) / range) * 30;\n return `${x.toFixed(2)},${y.toFixed(2)}`;\n })\n .join(' ');\n\n return (\n <svg\n viewBox=\"0 0 100 30\"\n preserveAspectRatio=\"none\"\n className={cn('mt-3 h-8 w-full', COLOR_STROKE[color])}\n role=\"img\"\n aria-label={t('arqel.aria.stat_sparkline', 'Trend sparkline')}\n data-testid=\"stat-card-sparkline\"\n >\n <polyline\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n points={coords}\n />\n </svg>\n );\n}\n\nexport function StatCard({ widget, className, columnSpan }: StatCardProps) {\n const { heading, description, value, statDescription, descriptionIcon, color, chart, url } =\n widget;\n const locale = useArqelLocale();\n const numberFormatter = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n\n // Numeric KPI values are grouped/decimal-formatted for the active locale\n // (e.g. `1234567` → `1.234.567` under pt-BR). Strings pass through verbatim\n // so server-formatted values (currency, percentages) stay intact.\n const displayValue =\n typeof value === 'number' && Number.isFinite(value)\n ? numberFormatter.format(value)\n : (value ?? '—');\n\n const hasChart = Array.isArray(chart) && chart.length >= 2;\n\n const body: ReactNode = (\n <>\n <div className={cn('text-4xl font-bold tabular-nums', COLOR_TEXT[color])}>{displayValue}</div>\n {statDescription && (\n <div className=\"mt-2 flex items-center gap-1 text-xs text-muted-foreground\">\n {descriptionIcon && (\n <span aria-hidden=\"true\" data-testid=\"stat-card-icon\">\n {/* Icon name passed through; an icon registry resolves it app-side. */}\n {descriptionIcon}\n </span>\n )}\n <span>{statDescription}</span>\n </div>\n )}\n {hasChart && <Sparkline points={chart as number[]} color={color} />}\n </>\n );\n\n const inner = url ? (\n <a\n href={url}\n className=\"block rounded outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-testid=\"stat-card-link\"\n >\n {body}\n </a>\n ) : (\n body\n );\n\n return (\n <WidgetWrapper\n heading={heading}\n description={description}\n columnSpan={columnSpan}\n className={className}\n >\n {inner}\n </WidgetWrapper>\n );\n}\n"]}
@@ -1,4 +1,6 @@
1
1
  import { colorFor } from './chunk-L3JBBN4H.js';
2
+ import { useArqelLocale, useArqelTranslations } from '@arqel-dev/react/utils';
3
+ import { useMemo } from 'react';
2
4
  import { ResponsiveContainer, PieChart as PieChart$1, Pie, Cell, Tooltip, Legend } from 'recharts';
3
5
  import { jsx, jsxs } from 'react/jsx-runtime';
4
6
 
@@ -9,9 +11,12 @@ function PieChart({
9
11
  innerRadius = 0,
10
12
  testId = "chart-pie"
11
13
  }) {
14
+ const locale = useArqelLocale();
15
+ const t = useArqelTranslations();
16
+ const nf = useMemo(() => new Intl.NumberFormat(locale), [locale]);
12
17
  const first = chartData.datasets[0];
13
18
  const slices = (first?.data ?? []).map((value, i) => ({
14
- name: chartData.labels[i] ?? `Slice ${i + 1}`,
19
+ name: chartData.labels[i] ?? t("arqel.chart.slice_fallback", "Slice :number", { number: i + 1 }),
15
20
  value
16
21
  }));
17
22
  return /* @__PURE__ */ jsx("div", { "data-testid": testId, style: { width: "100%", height }, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart$1, { children: [
@@ -23,15 +28,15 @@ function PieChart({
23
28
  nameKey: "name",
24
29
  innerRadius,
25
30
  outerRadius: "80%",
26
- label: true,
31
+ label: (entry) => nf.format(Number(entry.value)),
27
32
  children: slices.map((slice, i) => /* @__PURE__ */ jsx(Cell, { fill: colorFor(first ?? { label: "", data: [] }, i) }, slice.name))
28
33
  }
29
34
  ),
30
- /* @__PURE__ */ jsx(Tooltip, {}),
35
+ /* @__PURE__ */ jsx(Tooltip, { formatter: (v) => nf.format(Number(v)) }),
31
36
  showLegend ? /* @__PURE__ */ jsx(Legend, {}) : null
32
37
  ] }) }) });
33
38
  }
34
39
 
35
40
  export { PieChart };
36
- //# sourceMappingURL=chunk-C5H44NSP.js.map
37
- //# sourceMappingURL=chunk-C5H44NSP.js.map
41
+ //# sourceMappingURL=chunk-WZRPGPLH.js.map
42
+ //# sourceMappingURL=chunk-WZRPGPLH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/widgets/charts/PieChart.tsx"],"names":["RechartsPieChart"],"mappings":";;;;;;AAiBO,SAAS,QAAA,CAAS;AAAA,EACvB,SAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA,GAAc,CAAA;AAAA,EACd,MAAA,GAAS;AACX,CAAA,EAAkB;AAChB,EAAA,MAAM,SAAS,cAAA,EAAe;AAC9B,EAAA,MAAM,IAAI,oBAAA,EAAqB;AAC/B,EAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,MAAM,IAAI,IAAA,CAAK,aAAa,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAChE,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,QAAA,CAAS,CAAC,CAAA;AAClC,EAAA,MAAM,MAAA,GAAA,CAAU,OAAO,IAAA,IAAQ,IAAI,GAAA,CAAI,CAAC,OAAO,CAAA,MAAO;AAAA,IACpD,IAAA,EACE,SAAA,CAAU,MAAA,CAAO,CAAC,CAAA,IAAK,CAAA,CAAE,4BAAA,EAA8B,eAAA,EAAiB,EAAE,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAG,CAAA;AAAA,IAC3F;AAAA,GACF,CAAE,CAAA;AAEF,EAAA,2BACG,KAAA,EAAA,EAAI,aAAA,EAAa,MAAA,EAAQ,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,MAAA,EAAO,EACvD,8BAAC,mBAAA,EAAA,EAAoB,KAAA,EAAM,QAAO,MAAA,EAAO,MAAA,EACvC,+BAACA,UAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,MAAA;AAAA,QACN,OAAA,EAAQ,OAAA;AAAA,QACR,OAAA,EAAQ,MAAA;AAAA,QACR,WAAA;AAAA,QACA,WAAA,EAAY,KAAA;AAAA,QACZ,KAAA,EAAO,CAAC,KAAA,KAAU,EAAA,CAAG,OAAO,MAAA,CAAO,KAAA,CAAM,KAAK,CAAC,CAAA;AAAA,QAE9C,QAAA,EAAA,MAAA,CAAO,IAAI,CAAC,KAAA,EAAO,sBAClB,GAAA,CAAC,IAAA,EAAA,EAAsB,MAAM,QAAA,CAAS,KAAA,IAAS,EAAE,KAAA,EAAO,EAAA,EAAI,MAAM,EAAC,IAAK,CAAC,CAAA,EAAA,EAA9D,KAAA,CAAM,IAA2D,CAC7E;AAAA;AAAA,KACH;AAAA,oBACA,GAAA,CAAC,OAAA,EAAA,EAAQ,SAAA,EAAW,CAAC,CAAA,KAAM,GAAG,MAAA,CAAO,MAAA,CAAO,CAAC,CAAC,CAAA,EAAG,CAAA;AAAA,IAChD,UAAA,mBAAa,GAAA,CAAC,MAAA,EAAA,EAAO,CAAA,GAAK;AAAA,GAAA,EAC7B,GACF,CAAA,EACF,CAAA;AAEJ","file":"chunk-WZRPGPLH.js","sourcesContent":["import { useArqelLocale, useArqelTranslations } from '@arqel-dev/react/utils';\nimport { useMemo } from 'react';\nimport {\n Cell,\n Legend,\n Pie,\n PieChart as RechartsPieChart,\n ResponsiveContainer,\n Tooltip,\n} from 'recharts';\nimport { type ChartSubProps, colorFor } from '../types';\n\nexport interface PieChartProps extends ChartSubProps {\n innerRadius?: number | undefined;\n testId?: string | undefined;\n}\n\nexport function PieChart({\n chartData,\n height,\n showLegend,\n innerRadius = 0,\n testId = 'chart-pie',\n}: PieChartProps) {\n const locale = useArqelLocale();\n const t = useArqelTranslations();\n const nf = useMemo(() => new Intl.NumberFormat(locale), [locale]);\n const first = chartData.datasets[0];\n const slices = (first?.data ?? []).map((value, i) => ({\n name:\n chartData.labels[i] ?? t('arqel.chart.slice_fallback', 'Slice :number', { number: i + 1 }),\n value,\n }));\n\n return (\n <div data-testid={testId} style={{ width: '100%', height }}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RechartsPieChart>\n <Pie\n data={slices}\n dataKey=\"value\"\n nameKey=\"name\"\n innerRadius={innerRadius}\n outerRadius=\"80%\"\n label={(entry) => nf.format(Number(entry.value))}\n >\n {slices.map((slice, i) => (\n <Cell key={slice.name} fill={colorFor(first ?? { label: '', data: [] }, i)} />\n ))}\n </Pie>\n <Tooltip formatter={(v) => nf.format(Number(v))} />\n {showLegend ? <Legend /> : null}\n </RechartsPieChart>\n </ResponsiveContainer>\n </div>\n );\n}\n"]}
@@ -1,7 +1,8 @@
1
1
  import { PageHeader } from './chunk-MXUXMHOK.js';
2
- import { FormActions } from './chunk-MTZJDFQ6.js';
3
- import { FormRenderer } from './chunk-4JJS2SVS.js';
2
+ import { FormActions } from './chunk-MZMYV43C.js';
3
+ import { FormRenderer } from './chunk-CMNZLA32.js';
4
4
  import { useArqelForm } from '@arqel-dev/hooks';
5
+ import { useArqelTranslations } from '@arqel-dev/react/utils';
5
6
  import { usePage, router } from '@inertiajs/react';
6
7
  import { jsxs, jsx } from 'react/jsx-runtime';
7
8
 
@@ -14,6 +15,7 @@ var FALLBACK_SCHEMA = {
14
15
  };
15
16
  function ArqelEditPage() {
16
17
  const page = usePage();
18
+ const t = useArqelTranslations();
17
19
  const props = page.props;
18
20
  const fields = props.fields ?? [];
19
21
  const record = props.record;
@@ -28,14 +30,10 @@ function ArqelEditPage() {
28
30
  preserveScroll: true
29
31
  });
30
32
  };
33
+ const label = props.resource?.label ?? t("arqel.pages.fallback", "record");
34
+ const editTitle = props.recordTitle ?? t("arqel.pages.edit", `Edit ${label}`, { label });
31
35
  return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
32
- /* @__PURE__ */ jsx(
33
- PageHeader,
34
- {
35
- title: props.recordTitle ?? `Edit ${props.resource?.label ?? "record"}`,
36
- description: props.recordSubtitle ?? null
37
- }
38
- ),
36
+ /* @__PURE__ */ jsx(PageHeader, { title: editTitle, description: props.recordSubtitle ?? null }),
39
37
  /* @__PURE__ */ jsxs("form", { onSubmit: submit, className: "space-y-6", children: [
40
38
  /* @__PURE__ */ jsx(
41
39
  FormRenderer,
@@ -53,5 +51,5 @@ function ArqelEditPage() {
53
51
  }
54
52
 
55
53
  export { ArqelEditPage };
56
- //# sourceMappingURL=chunk-QTUBBZVT.js.map
57
- //# sourceMappingURL=chunk-QTUBBZVT.js.map
54
+ //# sourceMappingURL=chunk-YQ6KXR3U.js.map
55
+ //# sourceMappingURL=chunk-YQ6KXR3U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pages/ArqelEditPage.tsx"],"names":[],"mappings":";;;;;;;;AAkBA,IAAM,eAAA,GAA8B;AAAA,EAClC,QAAQ,EAAC;AAAA,EACT,OAAA,EAAS,CAAA;AAAA,EACT,KAAA,EAAO,IAAA;AAAA,EACP,MAAA,EAAQ,KAAA;AAAA,EACR,QAAA,EAAU;AACZ,CAAA;AASe,SAAR,aAAA,GAAuF;AAC5F,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,IAAI,oBAAA,EAAqB;AAC/B,EAAA,MAAM,QAAQ,IAAA,CAAK,KAAA;AACnB,EAAA,MAAM,MAAA,GAAU,KAAA,CAAM,MAAA,IAAU,EAAC;AACjC,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA;AACrB,EAAA,MAAM,MAAA,GAAU,MAA2C,IAAA,IAAQ,eAAA;AAEnE,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAE5C,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAuB;AACrC,IAAA,CAAA,CAAE,cAAA,EAAe;AACjB,IAAA,MAAM,EAAA,GAAK,MAAA,CAAQ,MAAA,EAAiD,EAAA,IAAM,EAAE,CAAA;AAC5E,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,QAAA,EAAU,IAAA,IAAQ,EAAA;AACrC,IAAA,MAAM,QAAA,GAAW,KAAA,CAAM,QAAA,EAAU,SAAA,IAAa,QAAA;AAC9C,IAAA,MAAA,CAAO,GAAA,CAAI,GAAG,QAAQ,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,EAAI,IAAA,CAAK,IAAA,EAA+B;AAAA,MAC1E,cAAA,EAAgB;AAAA,KACjB,CAAA;AAAA,EACH,CAAA;AAKA,EAAA,MAAM,QAAQ,KAAA,CAAM,QAAA,EAAU,KAAA,IAAS,CAAA,CAAE,wBAAwB,QAAQ,CAAA;AACzE,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,WAAA,IAAe,CAAA,CAAE,kBAAA,EAAoB,QAAQ,KAAK,CAAA,CAAA,EAAI,EAAE,KAAA,EAAO,CAAA;AAEvF,EAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,cAAW,KAAA,EAAO,SAAA,EAAW,WAAA,EAAa,KAAA,CAAM,kBAAkB,IAAA,EAAM,CAAA;AAAA,oBACzE,IAAA,CAAC,MAAA,EAAA,EAAK,QAAA,EAAU,MAAA,EAAQ,WAAU,WAAA,EAChC,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UACC,MAAA;AAAA,UACA,MAAA;AAAA,UACA,QAAQ,IAAA,CAAK,IAAA;AAAA,UACb,UAAU,CAAC,IAAA,EAAM,UAAU,IAAA,CAAK,OAAA,CAAQ,MAAM,KAAK,CAAA;AAAA,UACnD,QAAQ,IAAA,CAAK;AAAA;AAAA,OACf;AAAA,sBACA,GAAA,CAAC,WAAA,EAAA,EAAY,UAAA,EAAY,IAAA,CAAK,UAAA,EAAY,UAAU,MAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAK,EAAG;AAAA,KAAA,EACnF;AAAA,GAAA,EACF,CAAA;AAEJ","file":"chunk-YQ6KXR3U.js","sourcesContent":["/**\n * Default Inertia page for `arqel::edit`.\n *\n * Same shape as `ArqelCreatePage` but seeds the form with the\n * server-emitted `record`. Submission posts to PUT `/{slug}/{id}`.\n */\n\nimport { useArqelForm } from '@arqel-dev/hooks';\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { FieldSchema } from '@arqel-dev/types/fields';\nimport type { FormSchema } from '@arqel-dev/types/forms';\nimport type { RecordType, ResourceEditProps } from '@arqel-dev/types/resources';\nimport { router, usePage } from '@inertiajs/react';\nimport type { FormEvent, JSX } from 'react';\nimport { FormActions } from '../form/FormActions.js';\nimport { FormRenderer } from '../form/FormRenderer.js';\nimport { PageHeader } from '../utility/PageHeader.js';\n\nconst FALLBACK_SCHEMA: FormSchema = {\n schema: [],\n columns: 1,\n model: null,\n inline: false,\n disabled: false,\n};\n\ninterface ArqelFormShape {\n data: Record<string, unknown>;\n setData: (name: string, value: unknown) => void;\n errors: Record<string, string[]>;\n processing: boolean;\n}\n\nexport default function ArqelEditPage<TRecord extends RecordType = RecordType>(): JSX.Element {\n const page = usePage();\n const t = useArqelTranslations();\n const props = page.props as unknown as ResourceEditProps<TRecord>;\n const fields = (props.fields ?? []) as FieldSchema[];\n const record = props.record;\n const schema = (props as unknown as { form?: FormSchema }).form ?? FALLBACK_SCHEMA;\n\n const form = useArqelForm({ fields, record }) as unknown as ArqelFormShape;\n\n const submit = (e: FormEvent): void => {\n e.preventDefault();\n const id = String((record as { id?: string | number } | undefined)?.id ?? '');\n const slug = props.resource?.slug ?? '';\n const basePath = props.resource?.panelPath ?? '/admin';\n router.put(`${basePath}/${slug}/${id}`, form.data as Record<string, never>, {\n preserveScroll: true,\n });\n };\n\n // Pre-interpolate the label into the English fallback so the title stays\n // correct even when the `arqel.pages.edit` key is absent from the shared\n // dictionary (the hook does not re-interpolate a raw fallback).\n const label = props.resource?.label ?? t('arqel.pages.fallback', 'record');\n const editTitle = props.recordTitle ?? t('arqel.pages.edit', `Edit ${label}`, { label });\n\n return (\n <div className=\"space-y-6\">\n <PageHeader title={editTitle} description={props.recordSubtitle ?? null} />\n <form onSubmit={submit} className=\"space-y-6\">\n <FormRenderer\n schema={schema}\n fields={fields}\n values={form.data}\n onChange={(name, value) => form.setData(name, value)}\n errors={form.errors}\n />\n <FormActions processing={form.processing} onCancel={() => window.history.back()} />\n </form>\n </div>\n );\n}\n"]}
@@ -1,17 +1,18 @@
1
- import { WidgetWrapper, StatCard } from './chunk-WKWV36PG.js';
1
+ import { WidgetWrapper, StatCard } from './chunk-WMOBLT3Z.js';
2
2
  import { cn } from './chunk-B7ULUJVO.js';
3
- import { lazy, Suspense, useState, useRef, useEffect } from 'react';
3
+ import { useArqelTranslations, useArqelLocale } from '@arqel-dev/react/utils';
4
+ import { lazy, Suspense, useMemo, useState, useRef, useEffect } from 'react';
4
5
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
6
 
6
- var LineChart = lazy(() => import('./LineChart-GHMPHFZZ.js').then((m) => ({ default: m.LineChart })));
7
- var BarChart = lazy(() => import('./BarChart-KLHKTLO2.js').then((m) => ({ default: m.BarChart })));
8
- var AreaChart = lazy(() => import('./AreaChart-NMQ2RQGA.js').then((m) => ({ default: m.AreaChart })));
9
- var PieChart = lazy(() => import('./PieChart-T2VQOFPP.js').then((m) => ({ default: m.PieChart })));
7
+ var LineChart = lazy(() => import('./LineChart-RRPGAZON.js').then((m) => ({ default: m.LineChart })));
8
+ var BarChart = lazy(() => import('./BarChart-E52NJSJE.js').then((m) => ({ default: m.BarChart })));
9
+ var AreaChart = lazy(() => import('./AreaChart-JAZ6LUYG.js').then((m) => ({ default: m.AreaChart })));
10
+ var PieChart = lazy(() => import('./PieChart-SGN7V5LQ.js').then((m) => ({ default: m.PieChart })));
10
11
  var DonutChart = lazy(
11
- () => import('./DonutChart-L56R4QF2.js').then((m) => ({ default: m.DonutChart }))
12
+ () => import('./DonutChart-IGSF4LEB.js').then((m) => ({ default: m.DonutChart }))
12
13
  );
13
14
  var RadarChart = lazy(
14
- () => import('./RadarChart-CSWR5AO7.js').then((m) => ({ default: m.RadarChart }))
15
+ () => import('./RadarChart-3AOM736J.js').then((m) => ({ default: m.RadarChart }))
15
16
  );
16
17
  var REGISTRY = {
17
18
  line: LineChart,
@@ -22,6 +23,7 @@ var REGISTRY = {
22
23
  radar: RadarChart
23
24
  };
24
25
  function ChartCard({ widget }) {
26
+ const t = useArqelTranslations();
25
27
  const Chart = REGISTRY[widget.chartType] ?? LineChart;
26
28
  return /* @__PURE__ */ jsx(WidgetWrapper, { heading: widget.heading, description: widget.description, children: /* @__PURE__ */ jsx(
27
29
  Suspense,
@@ -30,7 +32,7 @@ function ChartCard({ widget }) {
30
32
  "div",
31
33
  {
32
34
  role: "status",
33
- "aria-label": "Loading chart",
35
+ "aria-label": t("arqel.aria.chart_loading", "Loading chart"),
34
36
  "data-testid": "chart-fallback",
35
37
  className: "animate-pulse rounded bg-muted",
36
38
  style: { height: widget.height }
@@ -100,6 +102,7 @@ function SelectControl({
100
102
  value,
101
103
  onChange
102
104
  }) {
105
+ const t = useArqelTranslations();
103
106
  const options = normaliseOptions(filter.options);
104
107
  const label = filter.label ?? filter.name;
105
108
  if (filter.multiple) {
@@ -132,7 +135,7 @@ function SelectControl({
132
135
  value: value === void 0 || value === null ? "" : String(value),
133
136
  onChange: (e) => onChange(e.target.value === "" ? null : e.target.value),
134
137
  children: [
135
- /* @__PURE__ */ jsx("option", { value: "", children: "All" }),
138
+ /* @__PURE__ */ jsx("option", { value: "", children: t("table.filters.all", "All") }),
136
139
  options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
137
140
  ]
138
141
  }
@@ -144,17 +147,19 @@ function DateRangeControl({
144
147
  value,
145
148
  onChange
146
149
  }) {
150
+ const t = useArqelTranslations();
151
+ const label = filter.label ?? filter.name;
147
152
  const range = value && typeof value === "object" ? value : {};
148
153
  const fromValue = typeof range.from === "string" ? range.from : "";
149
154
  const toValue = typeof range.to === "string" ? range.to : "";
150
155
  return /* @__PURE__ */ jsxs("fieldset", { className: "flex flex-col gap-1 text-xs text-muted-foreground", children: [
151
- /* @__PURE__ */ jsx("legend", { children: filter.label ?? filter.name }),
156
+ /* @__PURE__ */ jsx("legend", { children: label }),
152
157
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
153
158
  /* @__PURE__ */ jsx(
154
159
  "input",
155
160
  {
156
161
  type: "date",
157
- "aria-label": `${filter.label ?? filter.name} from`,
162
+ "aria-label": t("table.filters.date_from", `${label} from`, { label }),
158
163
  className: controlClasses(),
159
164
  value: fromValue,
160
165
  onChange: (e) => onChange({ from: e.target.value || null, to: range.to ?? null })
@@ -165,7 +170,7 @@ function DateRangeControl({
165
170
  "input",
166
171
  {
167
172
  type: "date",
168
- "aria-label": `${filter.label ?? filter.name} to`,
173
+ "aria-label": t("table.filters.date_to", `${label} to`, { label }),
169
174
  className: controlClasses(),
170
175
  value: toValue,
171
176
  onChange: (e) => onChange({ from: range.from ?? null, to: e.target.value || null })
@@ -175,6 +180,9 @@ function DateRangeControl({
175
180
  ] });
176
181
  }
177
182
  function TableCard({ widget, className }) {
183
+ const t = useArqelTranslations();
184
+ const locale = useArqelLocale();
185
+ const numberFormatter = useMemo(() => new Intl.NumberFormat(locale), [locale]);
178
186
  return /* @__PURE__ */ jsx(
179
187
  WidgetWrapper,
180
188
  {
@@ -196,19 +204,25 @@ function TableCard({ widget, className }) {
196
204
  "tr",
197
205
  {
198
206
  className: "border-b border-border last:border-0",
199
- children: widget.columns.map((column) => /* @__PURE__ */ jsx("td", { className: "px-2 py-1.5", children: formatCell(record[column.name]) }, column.name))
207
+ children: widget.columns.map((column) => /* @__PURE__ */ jsx("td", { className: "px-2 py-1.5", children: formatCell(record[column.name], numberFormatter, t) }, column.name))
200
208
  },
201
209
  rowIndex
202
210
  )) })
203
211
  ] }) }),
204
- widget.seeAllUrl && /* @__PURE__ */ jsx("div", { className: "mt-3 text-right", children: /* @__PURE__ */ jsx("a", { href: widget.seeAllUrl, className: "text-sm text-primary", children: "See all \u2192" }) })
212
+ widget.seeAllUrl && /* @__PURE__ */ jsx("div", { className: "mt-3 text-right", children: /* @__PURE__ */ jsx("a", { href: widget.seeAllUrl, className: "text-sm text-primary", children: t("widgets.table.see_all", "See all \u2192") }) })
205
213
  ] })
206
214
  }
207
215
  );
208
216
  }
209
- function formatCell(value) {
217
+ function formatCell(value, numberFormatter, t) {
210
218
  if (value === null || value === void 0) return "";
211
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
219
+ if (typeof value === "number") {
220
+ return Number.isFinite(value) ? numberFormatter.format(value) : String(value);
221
+ }
222
+ if (typeof value === "boolean") {
223
+ return value ? t("table.boolean.true_label", "true") : t("table.boolean.false_label", "false");
224
+ }
225
+ if (typeof value === "string") {
212
226
  return String(value);
213
227
  }
214
228
  try {
@@ -218,6 +232,7 @@ function formatCell(value) {
218
232
  }
219
233
  }
220
234
  function WidgetRenderer({ widget, filterValues, fetcher }) {
235
+ const t = useArqelTranslations();
221
236
  const [data, setData] = useState(widget.data ?? null);
222
237
  const filterRef = useRef(filterValues);
223
238
  filterRef.current = filterValues;
@@ -260,11 +275,9 @@ function WidgetRenderer({ widget, filterValues, fetcher }) {
260
275
  case "table":
261
276
  return /* @__PURE__ */ jsx(TableCard, { widget: merged });
262
277
  default:
263
- return /* @__PURE__ */ jsxs("div", { role: "alert", className: "text-sm text-red-600", children: [
264
- "Widget type ",
265
- widget.type,
266
- " not registered"
267
- ] });
278
+ return /* @__PURE__ */ jsx("div", { role: "alert", className: "text-sm text-red-600", children: t("widgets.unknown_type", `Widget type ${widget.type} not registered`, {
279
+ type: widget.type
280
+ }) });
268
281
  }
269
282
  }
270
283
  function withFilters(baseUrl, filters) {
@@ -366,5 +379,5 @@ function normaliseFilters(raw) {
366
379
  }
367
380
 
368
381
  export { ChartCard, DashboardFilters, DashboardGrid, TableCard, WidgetRenderer };
369
- //# sourceMappingURL=chunk-47HD7ALI.js.map
370
- //# sourceMappingURL=chunk-47HD7ALI.js.map
382
+ //# sourceMappingURL=chunk-YYQ45W25.js.map
383
+ //# sourceMappingURL=chunk-YYQ45W25.js.map