@ai-matrx/design-system 0.21.13 → 0.22.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 (61) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/content-transfer.cjs +1 -0
  3. package/dist/content-transfer.cjs.map +1 -1
  4. package/dist/content-transfer.js +1 -0
  5. package/dist/content-transfer.js.map +1 -1
  6. package/dist/data-table/copy-helpers.cjs.map +1 -1
  7. package/dist/data-table/copy-helpers.d.cts +2 -1
  8. package/dist/data-table/copy-helpers.d.ts +2 -1
  9. package/dist/data-table/copy-helpers.js.map +1 -1
  10. package/dist/data-table/data-row-inspector.cjs +1 -0
  11. package/dist/data-table/data-row-inspector.cjs.map +1 -1
  12. package/dist/data-table/data-row-inspector.js +1 -0
  13. package/dist/data-table/data-row-inspector.js.map +1 -1
  14. package/dist/data-table/data-row-window.cjs +1 -0
  15. package/dist/data-table/data-row-window.cjs.map +1 -1
  16. package/dist/data-table/data-row-window.js +1 -0
  17. package/dist/data-table/data-row-window.js.map +1 -1
  18. package/dist/data-table/filter-engine.cjs +6 -2
  19. package/dist/data-table/filter-engine.cjs.map +1 -1
  20. package/dist/data-table/filter-engine.d.cts +2 -1
  21. package/dist/data-table/filter-engine.d.ts +2 -1
  22. package/dist/data-table/filter-engine.js +6 -2
  23. package/dist/data-table/filter-engine.js.map +1 -1
  24. package/dist/data-table/host.d.cts +2 -1
  25. package/dist/data-table/host.d.ts +2 -1
  26. package/dist/data-table/index.cjs +1547 -425
  27. package/dist/data-table/index.cjs.map +1 -1
  28. package/dist/data-table/index.d.cts +91 -3
  29. package/dist/data-table/index.d.ts +91 -3
  30. package/dist/data-table/index.js +1549 -423
  31. package/dist/data-table/index.js.map +1 -1
  32. package/dist/data-table/infer-filter.cjs.map +1 -1
  33. package/dist/data-table/infer-filter.d.cts +2 -1
  34. package/dist/data-table/infer-filter.d.ts +2 -1
  35. package/dist/data-table/infer-filter.js.map +1 -1
  36. package/dist/data-table/layered-filters.d.cts +2 -1
  37. package/dist/data-table/layered-filters.d.ts +2 -1
  38. package/dist/data-table/query-control.cjs.map +1 -1
  39. package/dist/data-table/query-control.d.cts +2 -1
  40. package/dist/data-table/query-control.d.ts +2 -1
  41. package/dist/data-table/query-control.js.map +1 -1
  42. package/dist/data-table/types.cjs.map +1 -1
  43. package/dist/data-table/types.d.cts +2 -1
  44. package/dist/data-table/types.d.ts +2 -1
  45. package/dist/data-table/url-state.d.cts +2 -1
  46. package/dist/data-table/url-state.d.ts +2 -1
  47. package/dist/data-table/xlsx.cjs.map +1 -1
  48. package/dist/data-table/xlsx.d.cts +2 -1
  49. package/dist/data-table/xlsx.d.ts +2 -1
  50. package/dist/data-table/xlsx.js.map +1 -1
  51. package/dist/field-formats/index.cjs +741 -0
  52. package/dist/field-formats/index.cjs.map +1 -0
  53. package/dist/field-formats/index.d.cts +45 -0
  54. package/dist/field-formats/index.d.ts +45 -0
  55. package/dist/field-formats/index.js +723 -0
  56. package/dist/field-formats/index.js.map +1 -0
  57. package/dist/types-BdbvlF9-.d.cts +204 -0
  58. package/dist/types-BdbvlF9-.d.ts +204 -0
  59. package/dist/{types-D9b_LfTB.d.ts → types-D-flTpK0.d.ts} +241 -1
  60. package/dist/{types-DaKPLM6T.d.cts → types-Sn249eoy.d.cts} +241 -1
  61. package/package.json +11 -1
@@ -3174,6 +3174,7 @@ var outcomeMessage = (result) => {
3174
3174
  const success = result;
3175
3175
  return success.delivered === "action" ? success.message ?? "Action completed" : success.delivered === "download-started" ? "Download started" : success.message ?? "Copied";
3176
3176
  }
3177
+ if (result.status === "queued") return `${result.message} ${result.remedy}`;
3177
3178
  return result.status === "degraded" ? `Copied as plain text: ${result.reason}` : result.status === "cancelled" ? "Cancelled" : result.message;
3178
3179
  };
3179
3180
  var materialIds = /* @__PURE__ */ new WeakMap();
@@ -5134,8 +5135,12 @@ function passesColumnFilter(value, filter) {
5134
5135
  return Boolean(value) === filter.value;
5135
5136
  }
5136
5137
  case "number": {
5137
- const n = typeof value === "number" ? value : Number(stringifyCellValue(value).replace(/[^0-9.-]/g, ""));
5138
- if (Number.isNaN(n)) return false;
5138
+ const raw = stringifyCellValue(value).trim();
5139
+ if (raw === "") return false;
5140
+ const normalized = raw.replace(/[^0-9.-]/g, "");
5141
+ if (normalized === "") return false;
5142
+ const n = typeof value === "number" ? value : Number(normalized);
5143
+ if (!Number.isFinite(n)) return false;
5139
5144
  if (filter.min !== void 0 && n < filter.min) return false;
5140
5145
  if (filter.max !== void 0 && n > filter.max) return false;
5141
5146
  return true;
@@ -7022,6 +7027,295 @@ function ColumnManagerDragHandle({ id, label }) {
7022
7027
 
7023
7028
  // src/data-table/saved-view-snapshot.ts
7024
7029
  import { z as z2 } from "zod";
7030
+
7031
+ // src/data-table/table-style.ts
7032
+ var TABLE_STYLE_VERSION = 1;
7033
+ var STYLE_COLORS = [
7034
+ "slate",
7035
+ "green",
7036
+ "amber",
7037
+ "red",
7038
+ "blue",
7039
+ "violet",
7040
+ "teal"
7041
+ ];
7042
+ function isStyleColor(v) {
7043
+ return typeof v === "string" && STYLE_COLORS.includes(v);
7044
+ }
7045
+ var COLOR_RULE_OPS = [
7046
+ "is",
7047
+ "is_not",
7048
+ "contains",
7049
+ "is_empty",
7050
+ "not_empty",
7051
+ "is_true",
7052
+ "is_false",
7053
+ "gt",
7054
+ "gte",
7055
+ "lt",
7056
+ "lte"
7057
+ ];
7058
+ var OPS_WITH_VALUE = [
7059
+ "is",
7060
+ "is_not",
7061
+ "contains",
7062
+ "gt",
7063
+ "gte",
7064
+ "lt",
7065
+ "lte"
7066
+ ];
7067
+ var COLOR_RULE_OP_LABELS = {
7068
+ is: "is",
7069
+ is_not: "is not",
7070
+ contains: "contains",
7071
+ is_empty: "is empty",
7072
+ not_empty: "is not empty",
7073
+ is_true: "is checked",
7074
+ is_false: "is unchecked",
7075
+ gt: "is greater than",
7076
+ gte: "is at least",
7077
+ lt: "is less than",
7078
+ lte: "is at most"
7079
+ };
7080
+ var EMPTY_TABLE_STYLE = { version: TABLE_STYLE_VERSION };
7081
+ var TABLE_STYLE_METADATA_KEY = "style";
7082
+ function tableStyleIsEmpty(style) {
7083
+ return !style.colorBy && (style.rules?.length ?? 0) === 0 && Object.keys(style.rows ?? {}).length === 0 && Object.keys(style.cells ?? {}).length === 0 && Object.keys(style.columns ?? {}).length === 0;
7084
+ }
7085
+ function isRecord(v) {
7086
+ return typeof v === "object" && v !== null && !Array.isArray(v);
7087
+ }
7088
+ function parseColorMap(raw) {
7089
+ const out = {};
7090
+ if (!isRecord(raw)) return out;
7091
+ for (const [k, v] of Object.entries(raw)) if (isStyleColor(v)) out[k] = v;
7092
+ return out;
7093
+ }
7094
+ function parseRule(raw) {
7095
+ if (!isRecord(raw)) return null;
7096
+ const { id, field, op, value, color, target } = raw;
7097
+ if (typeof id !== "string" || typeof field !== "string") return null;
7098
+ if (typeof op !== "string" || !COLOR_RULE_OPS.includes(op)) return null;
7099
+ if (!isStyleColor(color)) return null;
7100
+ if (target !== "row" && target !== "cell") return null;
7101
+ return {
7102
+ id,
7103
+ field,
7104
+ op,
7105
+ color,
7106
+ target,
7107
+ ...typeof value === "string" || typeof value === "number" ? { value: String(value) } : {}
7108
+ };
7109
+ }
7110
+ function parseTableStyle(raw) {
7111
+ if (!isRecord(raw)) return { ...EMPTY_TABLE_STYLE };
7112
+ const style = { version: TABLE_STYLE_VERSION };
7113
+ const colorBy = raw.colorBy;
7114
+ if (isRecord(colorBy) && typeof colorBy.field === "string" && (colorBy.target === "row" || colorBy.target === "cell")) {
7115
+ style.colorBy = { field: colorBy.field, target: colorBy.target };
7116
+ }
7117
+ if (Array.isArray(raw.rules)) {
7118
+ const rules = raw.rules.map(parseRule).filter((r) => r !== null);
7119
+ if (rules.length > 0) style.rules = rules;
7120
+ }
7121
+ const rows = parseColorMap(raw.rows);
7122
+ if (Object.keys(rows).length > 0) style.rows = rows;
7123
+ const columns = parseColorMap(raw.columns);
7124
+ if (Object.keys(columns).length > 0) style.columns = columns;
7125
+ if (isRecord(raw.cells)) {
7126
+ const cells = {};
7127
+ for (const [rowId, byField] of Object.entries(raw.cells)) {
7128
+ const parsed = parseColorMap(byField);
7129
+ if (Object.keys(parsed).length > 0) cells[rowId] = parsed;
7130
+ }
7131
+ if (Object.keys(cells).length > 0) style.cells = cells;
7132
+ }
7133
+ return style;
7134
+ }
7135
+ function tableStyleFromMetadata(metadata) {
7136
+ return parseTableStyle(isRecord(metadata) ? metadata[TABLE_STYLE_METADATA_KEY] : null);
7137
+ }
7138
+ function cellText(value) {
7139
+ if (value === null || value === void 0) return "";
7140
+ if (Array.isArray(value)) return value.map((v) => String(v)).join(", ");
7141
+ if (typeof value === "object") return JSON.stringify(value);
7142
+ return String(value);
7143
+ }
7144
+ function isEmptyValue(value) {
7145
+ if (value === null || value === void 0) return true;
7146
+ if (typeof value === "string") return value.trim() === "";
7147
+ if (Array.isArray(value)) return value.length === 0;
7148
+ return false;
7149
+ }
7150
+ function evaluateRule(rule, value) {
7151
+ switch (rule.op) {
7152
+ case "is_empty":
7153
+ return isEmptyValue(value);
7154
+ case "not_empty":
7155
+ return !isEmptyValue(value);
7156
+ case "is_true":
7157
+ return value === true;
7158
+ case "is_false":
7159
+ return value === false;
7160
+ case "is": {
7161
+ const want = (rule.value ?? "").trim().toLowerCase();
7162
+ if (Array.isArray(value)) {
7163
+ return value.some((v) => cellText(v).trim().toLowerCase() === want);
7164
+ }
7165
+ return cellText(value).trim().toLowerCase() === want;
7166
+ }
7167
+ case "is_not": {
7168
+ const want = (rule.value ?? "").trim().toLowerCase();
7169
+ if (Array.isArray(value)) {
7170
+ return !value.some((v) => cellText(v).trim().toLowerCase() === want);
7171
+ }
7172
+ return cellText(value).trim().toLowerCase() !== want;
7173
+ }
7174
+ case "contains": {
7175
+ const want = (rule.value ?? "").trim().toLowerCase();
7176
+ if (!want) return false;
7177
+ return cellText(value).toLowerCase().includes(want);
7178
+ }
7179
+ case "gt":
7180
+ case "gte":
7181
+ case "lt":
7182
+ case "lte": {
7183
+ const left = typeof value === "number" ? value : Number(cellText(value));
7184
+ const right = Number(rule.value);
7185
+ if (!Number.isFinite(left) || !Number.isFinite(right)) return false;
7186
+ if (rule.op === "gt") return left > right;
7187
+ if (rule.op === "gte") return left >= right;
7188
+ if (rule.op === "lt") return left < right;
7189
+ return left <= right;
7190
+ }
7191
+ }
7192
+ }
7193
+ function colorForChoice(choices, value) {
7194
+ if (!choices || choices.length === 0) return void 0;
7195
+ const wanted = String(value);
7196
+ const index = choices.findIndex((c) => c.value === wanted);
7197
+ if (index === -1) return void 0;
7198
+ const declared = choices[index]?.color;
7199
+ if (isStyleColor(declared)) return declared;
7200
+ return STYLE_COLORS[index % STYLE_COLORS.length];
7201
+ }
7202
+ var BOOLEAN_TRUE_COLOR = "green";
7203
+ function colorByFor(style, target, data, choiceColorFor) {
7204
+ const cb = style.colorBy;
7205
+ if (!cb || cb.target !== target) return null;
7206
+ const value = data[cb.field];
7207
+ if (value === true) return BOOLEAN_TRUE_COLOR;
7208
+ if (value === false || isEmptyValue(value)) return null;
7209
+ const first = Array.isArray(value) ? value[0] : value;
7210
+ return choiceColorFor(cb.field, first) ?? null;
7211
+ }
7212
+ function ruleColorFor(style, target, data, fieldName) {
7213
+ for (const rule of style.rules ?? []) {
7214
+ if (rule.target !== target) continue;
7215
+ if (target === "cell" && rule.field !== fieldName) continue;
7216
+ if (evaluateRule(rule, data[rule.field])) return rule.color;
7217
+ }
7218
+ return null;
7219
+ }
7220
+ function resolveRowColor(style, row, choiceColorFor) {
7221
+ return style.rows?.[row.id] ?? ruleColorFor(style, "row", row.data) ?? colorByFor(style, "row", row.data, choiceColorFor);
7222
+ }
7223
+ function resolveCellColor(style, row, fieldName, choiceColorFor) {
7224
+ const manual = style.cells?.[row.id]?.[fieldName];
7225
+ if (manual) return manual;
7226
+ const rule = ruleColorFor(style, "cell", row.data, fieldName);
7227
+ if (rule) return rule;
7228
+ if (style.colorBy?.target === "cell" && style.colorBy.field === fieldName) {
7229
+ const cb = colorByFor(style, "cell", row.data, choiceColorFor);
7230
+ if (cb) return cb;
7231
+ }
7232
+ return style.columns?.[fieldName] ?? null;
7233
+ }
7234
+ var ROW_TINT_CLASS = {
7235
+ slate: "bg-slate-100/70 dark:bg-slate-800/40",
7236
+ green: "bg-green-50 dark:bg-green-950/40",
7237
+ amber: "bg-amber-50 dark:bg-amber-950/40",
7238
+ red: "bg-red-50 dark:bg-red-950/40",
7239
+ blue: "bg-blue-50 dark:bg-blue-950/40",
7240
+ violet: "bg-violet-50 dark:bg-violet-950/40",
7241
+ teal: "bg-teal-50 dark:bg-teal-950/40"
7242
+ };
7243
+ var CELL_TINT_CLASS = {
7244
+ slate: "bg-slate-200/70 dark:bg-slate-700/50",
7245
+ green: "bg-green-100 dark:bg-green-900/50",
7246
+ amber: "bg-amber-100 dark:bg-amber-900/50",
7247
+ red: "bg-red-100 dark:bg-red-900/50",
7248
+ blue: "bg-blue-100 dark:bg-blue-900/50",
7249
+ violet: "bg-violet-100 dark:bg-violet-900/50",
7250
+ teal: "bg-teal-100 dark:bg-teal-900/50"
7251
+ };
7252
+ var SWATCH_CLASS = {
7253
+ slate: "bg-slate-400",
7254
+ green: "bg-green-500",
7255
+ amber: "bg-amber-400",
7256
+ red: "bg-red-500",
7257
+ blue: "bg-blue-500",
7258
+ violet: "bg-violet-500",
7259
+ teal: "bg-teal-500"
7260
+ };
7261
+ var STYLE_COLOR_LABELS = {
7262
+ slate: "Gray",
7263
+ green: "Green",
7264
+ amber: "Amber",
7265
+ red: "Red",
7266
+ blue: "Blue",
7267
+ violet: "Violet",
7268
+ teal: "Teal"
7269
+ };
7270
+ var stylePath = {
7271
+ colorBy: () => ["colorBy"],
7272
+ rules: () => ["rules"],
7273
+ row: (rowId) => ["rows", rowId],
7274
+ cell: (rowId, fieldName) => ["cells", rowId, fieldName],
7275
+ column: (fieldName) => ["columns", fieldName]
7276
+ };
7277
+ function applyStylePath(style, path2, value) {
7278
+ const next = { ...style };
7279
+ const [head, a, b] = path2;
7280
+ switch (head) {
7281
+ case "colorBy":
7282
+ next.colorBy = value === null ? null : parseTableStyle({ colorBy: value }).colorBy ?? null;
7283
+ break;
7284
+ case "rules":
7285
+ next.rules = value === null ? [] : parseTableStyle({ rules: value }).rules ?? [];
7286
+ break;
7287
+ case "rows": {
7288
+ const rows = { ...style.rows ?? {} };
7289
+ if (a === void 0) break;
7290
+ if (isStyleColor(value)) rows[a] = value;
7291
+ else delete rows[a];
7292
+ next.rows = rows;
7293
+ break;
7294
+ }
7295
+ case "columns": {
7296
+ const columns = { ...style.columns ?? {} };
7297
+ if (a === void 0) break;
7298
+ if (isStyleColor(value)) columns[a] = value;
7299
+ else delete columns[a];
7300
+ next.columns = columns;
7301
+ break;
7302
+ }
7303
+ case "cells": {
7304
+ if (a === void 0 || b === void 0) break;
7305
+ const cells = { ...style.cells ?? {} };
7306
+ const byField = { ...cells[a] ?? {} };
7307
+ if (isStyleColor(value)) byField[b] = value;
7308
+ else delete byField[b];
7309
+ if (Object.keys(byField).length === 0) delete cells[a];
7310
+ else cells[a] = byField;
7311
+ next.cells = cells;
7312
+ break;
7313
+ }
7314
+ }
7315
+ return next;
7316
+ }
7317
+
7318
+ // src/data-table/saved-view-snapshot.ts
7025
7319
  var filterSchema = z2.union([
7026
7320
  z2.object({ kind: z2.literal("text"), value: z2.string(), mode: z2.enum(["contains", "empty", "not_empty", "null", "not_null"]).optional(), negated: z2.boolean().optional() }),
7027
7321
  z2.object({ kind: z2.literal("select"), value: z2.string(), values: z2.array(z2.string()).optional(), negated: z2.boolean().optional() }),
@@ -7039,7 +7333,13 @@ var snapshotSchema = z2.object({
7039
7333
  }),
7040
7334
  hidden: z2.array(z2.string().min(1)),
7041
7335
  widths: z2.record(z2.string(), z2.number().finite().positive()).optional()
7042
- })
7336
+ }),
7337
+ // The style is read by `parseTableStyle`, not described again here. That
7338
+ // reader is tolerant BY DESIGN — an unknown key, a retired color name or a
7339
+ // malformed rule is dropped, never thrown — and a Zod mirror of it would
7340
+ // reject a whole saved view over one stale rule, which is the opposite of
7341
+ // what a table must do when its colors go out of date.
7342
+ style: z2.unknown().optional()
7043
7343
  });
7044
7344
  function normalizeFilters(raw) {
7045
7345
  const filters = {};
@@ -7056,6 +7356,7 @@ function parseTableViewSnapshot(raw) {
7056
7356
  const parsed = snapshotSchema.safeParse(raw);
7057
7357
  if (!parsed.success) return null;
7058
7358
  const { query, columns } = parsed.data;
7359
+ const style = parsed.data.style === void 0 ? null : parseTableStyle(parsed.data.style);
7059
7360
  return {
7060
7361
  __kind: "matrx-table-view",
7061
7362
  version: 1,
@@ -7073,7 +7374,8 @@ function parseTableViewSnapshot(raw) {
7073
7374
  order: columns.order,
7074
7375
  hidden: columns.hidden,
7075
7376
  ...columns.widths === void 0 ? {} : { widths: columns.widths }
7076
- }
7377
+ },
7378
+ ...style === null || tableStyleIsEmpty(style) ? {} : { style }
7077
7379
  };
7078
7380
  }
7079
7381
 
@@ -7536,8 +7838,740 @@ function defaultRowTitle(row, columns) {
7536
7838
  return value ? isUuidValue(value) ? value.slice(0, 8) : value : "Details";
7537
7839
  }
7538
7840
 
7539
- // src/data-table/DirtySavePill.tsx
7841
+ // src/data-table/frozen-columns.ts
7842
+ var NO_FROZEN_COLUMNS = {
7843
+ offsets: {},
7844
+ active: false,
7845
+ selectionOffset: null
7846
+ };
7847
+ function resolveFrozenColumns(ids, isFrozen, widthOf, leadingWidth) {
7848
+ const run = [];
7849
+ for (const id of ids) {
7850
+ if (!isFrozen(id)) break;
7851
+ run.push(id);
7852
+ }
7853
+ if (run.length === 0) return NO_FROZEN_COLUMNS;
7854
+ if (leadingWidth === void 0) return NO_FROZEN_COLUMNS;
7855
+ const base = leadingWidth ?? 0;
7856
+ const offsets = {};
7857
+ let cursor = base;
7858
+ for (let i = 0; i < run.length; i += 1) {
7859
+ const id = run[i];
7860
+ offsets[id] = cursor;
7861
+ if (i === run.length - 1) break;
7862
+ const w = widthOf(id);
7863
+ if (w === void 0 || !Number.isFinite(w) || w <= 0) return NO_FROZEN_COLUMNS;
7864
+ cursor += w;
7865
+ }
7866
+ return {
7867
+ offsets,
7868
+ active: true,
7869
+ selectionOffset: leadingWidth === null ? null : 0
7870
+ };
7871
+ }
7872
+ function pixelWidth(width) {
7873
+ if (typeof width === "number") return Number.isFinite(width) ? width : void 0;
7874
+ if (typeof width === "string") {
7875
+ const m = /^(\d+(?:\.\d+)?)px$/.exec(width.trim());
7876
+ if (m) return Number(m[1]);
7877
+ }
7878
+ return void 0;
7879
+ }
7880
+ var FROZEN_CELL_CLASS = "sm:sticky sm:left-[var(--matrx-frozen-left)] sm:z-20 sm:bg-inherit";
7881
+ var FROZEN_HEADER_CLASS = "sm:sticky sm:left-[var(--matrx-frozen-left)] sm:z-30";
7882
+ var FROZEN_EDGE_CLASS = "sm:shadow-[inset_-1px_0_0_var(--border)]";
7883
+
7884
+ // src/field-formats/registry.ts
7885
+ import {
7886
+ formatDurationSeconds,
7887
+ formatFileSize,
7888
+ formatRelativeTime
7889
+ } from "@ai-matrx/kit/format";
7890
+ function formatSignedDuration(totalSeconds) {
7891
+ return formatDurationSeconds(totalSeconds, { signed: true });
7892
+ }
7893
+ function toNumber(value) {
7894
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
7895
+ if (typeof value === "string") {
7896
+ const cleaned = value.replace(/[,\s$€£¥%]/g, "");
7897
+ if (cleaned === "") return null;
7898
+ const n = Number(cleaned);
7899
+ return Number.isFinite(n) ? n : null;
7900
+ }
7901
+ return null;
7902
+ }
7903
+ function toText(value) {
7904
+ if (typeof value === "string") return value;
7905
+ if (typeof value === "number" || typeof value === "boolean")
7906
+ return String(value);
7907
+ return null;
7908
+ }
7909
+ function toDate(value) {
7910
+ if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;
7911
+ if (typeof value === "number") {
7912
+ const d = new Date(value);
7913
+ return Number.isNaN(d.getTime()) ? null : d;
7914
+ }
7915
+ if (typeof value === "string" && value.trim()) {
7916
+ const d = new Date(value);
7917
+ return Number.isNaN(d.getTime()) ? null : d;
7918
+ }
7919
+ return null;
7920
+ }
7921
+ function toList(value) {
7922
+ if (Array.isArray(value)) return value;
7923
+ if (typeof value === "string") {
7924
+ const trimmed = value.trim();
7925
+ if (trimmed.startsWith("[")) {
7926
+ try {
7927
+ const parsed = JSON.parse(trimmed);
7928
+ if (Array.isArray(parsed)) return parsed;
7929
+ } catch {
7930
+ }
7931
+ }
7932
+ if (trimmed === "") return [];
7933
+ return trimmed.split(",").map((s) => s.trim());
7934
+ }
7935
+ return null;
7936
+ }
7937
+ function groupedNumber(n, options) {
7938
+ return new Intl.NumberFormat(void 0, {
7939
+ useGrouping: options.useGrouping !== false,
7940
+ ...options.precision != null ? {
7941
+ minimumFractionDigits: options.precision,
7942
+ maximumFractionDigits: options.precision
7943
+ } : { maximumFractionDigits: 10 }
7944
+ }).format(n);
7945
+ }
7946
+ function affix(text, options) {
7947
+ return `${options.prefix ?? ""}${text}${options.suffix ?? ""}`;
7948
+ }
7949
+ var DURATION_TO_SECONDS = { milliseconds: 1e-3, seconds: 1, minutes: 60, hours: 3600 };
7950
+ function findChoice(choices, value) {
7951
+ if (!choices || choices.length === 0) return void 0;
7952
+ const exact = choices.find((c) => c.value === value);
7953
+ if (exact) return exact;
7954
+ const lowered = value.toLowerCase();
7955
+ return choices.find((c) => c.value.toLowerCase() === lowered);
7956
+ }
7957
+ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
7958
+ var URL_RE = /^(?:[a-z][a-z0-9+.-]*:\/\/\S+|(?:[a-z0-9-]+\.)+[a-z]{2,}(?:[:/?#]\S*)?)$/i;
7959
+ var HEX_RE = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
7960
+ var DEFS = [
7961
+ // ── Text ──────────────────────────────────────────────────────────────────
7962
+ {
7963
+ id: "text",
7964
+ label: "Text",
7965
+ description: "Plain single-line text",
7966
+ group: "Text",
7967
+ base: "string",
7968
+ editor: "text",
7969
+ // Deliberately no optionKeys — plain text is the default for every string
7970
+ // column, and giving it prefix/suffix controls puts an options row under
7971
+ // every column in the settings dialog for a setting almost nobody wants.
7972
+ format: (v, o) => {
7973
+ const t = toText(v);
7974
+ return t === null ? null : affix(t, o);
7975
+ },
7976
+ parse: (raw) => raw === "" || raw == null ? null : String(raw)
7977
+ },
7978
+ {
7979
+ id: "long_text",
7980
+ label: "Long text",
7981
+ description: "Multi-line text, edited in a larger box",
7982
+ group: "Text",
7983
+ base: "string",
7984
+ editor: "textarea",
7985
+ format: (v) => toText(v),
7986
+ parse: (raw) => raw === "" || raw == null ? null : String(raw)
7987
+ },
7988
+ {
7989
+ id: "markdown",
7990
+ label: "Markdown",
7991
+ description: "Rich text written as Markdown",
7992
+ group: "Text",
7993
+ base: "string",
7994
+ editor: "textarea",
7995
+ rich: true,
7996
+ format: (v) => toText(v),
7997
+ parse: (raw) => raw === "" || raw == null ? null : String(raw)
7998
+ },
7999
+ {
8000
+ id: "email",
8001
+ label: "Email",
8002
+ description: "Email address \u2014 click to compose",
8003
+ group: "Text",
8004
+ base: "string",
8005
+ editor: "email",
8006
+ rich: true,
8007
+ format: (v) => {
8008
+ const t = toText(v)?.trim();
8009
+ if (!t) return null;
8010
+ return EMAIL_RE.test(t) ? t : null;
8011
+ },
8012
+ parse: (raw) => raw === "" || raw == null ? null : String(raw).trim()
8013
+ },
8014
+ {
8015
+ id: "url",
8016
+ label: "Link",
8017
+ description: "Web address \u2014 click to open",
8018
+ group: "Text",
8019
+ base: "string",
8020
+ editor: "url",
8021
+ rich: true,
8022
+ format: (v) => {
8023
+ const t = toText(v)?.trim();
8024
+ if (!t) return null;
8025
+ if (/\s/.test(t)) return null;
8026
+ if (!URL_RE.test(t)) return null;
8027
+ try {
8028
+ new URL(t.includes("://") ? t : `https://${t}`);
8029
+ return t;
8030
+ } catch {
8031
+ return null;
8032
+ }
8033
+ },
8034
+ parse: (raw) => raw === "" || raw == null ? null : String(raw).trim()
8035
+ },
8036
+ {
8037
+ id: "phone",
8038
+ label: "Phone",
8039
+ description: "Phone number \u2014 click to call",
8040
+ group: "Text",
8041
+ base: "string",
8042
+ editor: "tel",
8043
+ rich: true,
8044
+ format: (v) => {
8045
+ const t = toText(v)?.trim();
8046
+ if (!t) return null;
8047
+ return (t.match(/\d/g) ?? []).length >= 7 ? t : null;
8048
+ },
8049
+ parse: (raw) => raw === "" || raw == null ? null : String(raw).trim()
8050
+ },
8051
+ {
8052
+ id: "color",
8053
+ label: "Color",
8054
+ description: "Hex color with a swatch",
8055
+ group: "Text",
8056
+ base: "string",
8057
+ editor: "color",
8058
+ rich: true,
8059
+ format: (v) => {
8060
+ const t = toText(v)?.trim();
8061
+ if (!t) return null;
8062
+ return HEX_RE.test(t) ? t.toLowerCase() : null;
8063
+ },
8064
+ parse: (raw) => raw === "" || raw == null ? null : String(raw).trim()
8065
+ },
8066
+ // ── Numbers ───────────────────────────────────────────────────────────────
8067
+ {
8068
+ id: "number",
8069
+ label: "Number",
8070
+ description: "Plain number",
8071
+ group: "Numbers",
8072
+ base: "number",
8073
+ alsoAccepts: ["integer"],
8074
+ editor: "number",
8075
+ numericAlign: true,
8076
+ optionKeys: ["useGrouping", "precision", "prefix", "suffix"],
8077
+ format: (v, o) => {
8078
+ const n = toNumber(v);
8079
+ return n === null ? null : affix(groupedNumber(n, o), o);
8080
+ },
8081
+ parse: (raw) => toNumber(raw)
8082
+ },
8083
+ {
8084
+ id: "decimal",
8085
+ label: "Decimal",
8086
+ description: "Number with fixed decimal places",
8087
+ group: "Numbers",
8088
+ base: "number",
8089
+ alsoAccepts: ["integer"],
8090
+ editor: "number",
8091
+ numericAlign: true,
8092
+ optionKeys: ["precision", "useGrouping", "prefix", "suffix"],
8093
+ format: (v, o) => {
8094
+ const n = toNumber(v);
8095
+ if (n === null) return null;
8096
+ return affix(groupedNumber(n, { ...o, precision: o.precision ?? 2 }), o);
8097
+ },
8098
+ parse: (raw) => toNumber(raw)
8099
+ },
8100
+ {
8101
+ id: "currency",
8102
+ label: "Currency",
8103
+ description: "Money \u2014 stored as a plain number, shown with a symbol",
8104
+ group: "Numbers",
8105
+ base: "number",
8106
+ alsoAccepts: ["integer"],
8107
+ editor: "number",
8108
+ numericAlign: true,
8109
+ optionKeys: ["currency", "precision"],
8110
+ format: (v, o) => {
8111
+ const n = toNumber(v);
8112
+ if (n === null) return null;
8113
+ const currency = (o.currency || "USD").toUpperCase();
8114
+ try {
8115
+ return new Intl.NumberFormat(void 0, {
8116
+ style: "currency",
8117
+ currency,
8118
+ ...o.precision != null ? {
8119
+ minimumFractionDigits: o.precision,
8120
+ maximumFractionDigits: o.precision
8121
+ } : {}
8122
+ }).format(n);
8123
+ } catch {
8124
+ return `${groupedNumber(n, { precision: o.precision ?? 2 })} ${currency}`;
8125
+ }
8126
+ },
8127
+ parse: (raw) => toNumber(raw)
8128
+ },
8129
+ {
8130
+ id: "percent",
8131
+ label: "Percent",
8132
+ description: "Percentage \u2014 stored as a plain number",
8133
+ group: "Numbers",
8134
+ base: "number",
8135
+ alsoAccepts: ["integer"],
8136
+ editor: "number",
8137
+ numericAlign: true,
8138
+ optionKeys: ["percentScale", "precision"],
8139
+ format: (v, o) => {
8140
+ const n = toNumber(v);
8141
+ if (n === null) return null;
8142
+ const shown = o.percentScale === "fraction" ? n * 100 : n;
8143
+ return `${groupedNumber(shown, o.precision === void 0 ? {} : { precision: o.precision })}%`;
8144
+ },
8145
+ parse: (raw) => toNumber(raw)
8146
+ },
8147
+ {
8148
+ id: "duration",
8149
+ label: "Duration",
8150
+ description: "Length of time, shown as h:mm:ss",
8151
+ group: "Numbers",
8152
+ base: "number",
8153
+ alsoAccepts: ["integer"],
8154
+ editor: "number",
8155
+ numericAlign: true,
8156
+ optionKeys: ["durationUnit"],
8157
+ format: (v, o) => {
8158
+ const n = toNumber(v);
8159
+ if (n === null) return null;
8160
+ return formatSignedDuration(n * DURATION_TO_SECONDS[o.durationUnit ?? "seconds"]);
8161
+ },
8162
+ parse: (raw) => toNumber(raw)
8163
+ },
8164
+ {
8165
+ id: "integer",
8166
+ label: "Whole number",
8167
+ description: "Integer with no decimal part",
8168
+ group: "Numbers",
8169
+ base: "integer",
8170
+ alsoAccepts: ["number"],
8171
+ editor: "number",
8172
+ numericAlign: true,
8173
+ optionKeys: ["useGrouping", "prefix", "suffix"],
8174
+ format: (v, o) => {
8175
+ const n = toNumber(v);
8176
+ if (n === null) return null;
8177
+ return affix(groupedNumber(Math.trunc(n), { ...o, precision: 0 }), o);
8178
+ },
8179
+ parse: (raw) => {
8180
+ const n = toNumber(raw);
8181
+ return n === null ? null : Math.trunc(n);
8182
+ }
8183
+ },
8184
+ {
8185
+ id: "rating",
8186
+ label: "Rating",
8187
+ description: "Score out of a maximum, shown as stars",
8188
+ group: "Numbers",
8189
+ base: "integer",
8190
+ alsoAccepts: ["number"],
8191
+ editor: "rating",
8192
+ rich: true,
8193
+ optionKeys: ["ratingMax"],
8194
+ format: (v, o) => {
8195
+ const n = toNumber(v);
8196
+ if (n === null) return null;
8197
+ const max = o.ratingMax ?? 5;
8198
+ if (n < 0 || n > max) return null;
8199
+ return `${n} / ${max}`;
8200
+ },
8201
+ parse: (raw) => {
8202
+ const n = toNumber(raw);
8203
+ return n === null ? null : Math.round(n);
8204
+ }
8205
+ },
8206
+ {
8207
+ id: "file_size",
8208
+ label: "File size",
8209
+ description: "Byte count shown as KB / MB / GB",
8210
+ group: "Numbers",
8211
+ base: "integer",
8212
+ alsoAccepts: ["number"],
8213
+ editor: "number",
8214
+ numericAlign: true,
8215
+ format: (v) => {
8216
+ const n = toNumber(v);
8217
+ return n === null ? null : formatFileSize(n);
8218
+ },
8219
+ parse: (raw) => {
8220
+ const n = toNumber(raw);
8221
+ return n === null ? null : Math.trunc(n);
8222
+ }
8223
+ },
8224
+ // ── Choice ────────────────────────────────────────────────────────────────
8225
+ {
8226
+ id: "boolean",
8227
+ label: "Yes / No",
8228
+ description: "True or false",
8229
+ group: "Choice",
8230
+ base: "boolean",
8231
+ editor: "checkbox",
8232
+ format: (v) => {
8233
+ if (typeof v === "boolean") return v ? "Yes" : "No";
8234
+ if (v === "true" || v === 1) return "Yes";
8235
+ if (v === "false" || v === 0) return "No";
8236
+ return null;
8237
+ },
8238
+ parse: (raw) => {
8239
+ if (typeof raw === "boolean") return raw;
8240
+ if (raw == null || raw === "") return null;
8241
+ return String(raw).toLowerCase() === "true" || raw === 1;
8242
+ }
8243
+ },
8244
+ // ── Dates ─────────────────────────────────────────────────────────────────
8245
+ {
8246
+ id: "date",
8247
+ label: "Date",
8248
+ description: "Calendar date",
8249
+ group: "Dates",
8250
+ base: "date",
8251
+ alsoAccepts: ["datetime", "string"],
8252
+ editor: "date",
8253
+ optionKeys: ["dateStyle"],
8254
+ format: (v, o) => {
8255
+ const d = toDate(v);
8256
+ if (!d) return null;
8257
+ return d.toLocaleDateString(void 0, {
8258
+ dateStyle: o.dateStyle ?? "medium"
8259
+ });
8260
+ },
8261
+ parse: (raw) => raw === "" || raw == null ? null : String(raw)
8262
+ },
8263
+ {
8264
+ id: "datetime",
8265
+ label: "Date & time",
8266
+ description: "Calendar date with a time of day",
8267
+ group: "Dates",
8268
+ base: "datetime",
8269
+ alsoAccepts: ["date", "string"],
8270
+ editor: "datetime",
8271
+ optionKeys: ["dateStyle"],
8272
+ format: (v, o) => {
8273
+ const d = toDate(v);
8274
+ if (!d) return null;
8275
+ return d.toLocaleString(void 0, {
8276
+ dateStyle: o.dateStyle ?? "medium",
8277
+ timeStyle: "short"
8278
+ });
8279
+ },
8280
+ parse: (raw) => raw === "" || raw == null ? null : String(raw)
8281
+ },
8282
+ {
8283
+ id: "relative_time",
8284
+ label: "Relative time",
8285
+ description: 'Shown as "3 days ago"',
8286
+ group: "Dates",
8287
+ base: "datetime",
8288
+ alsoAccepts: ["date", "string"],
8289
+ editor: "datetime",
8290
+ format: (v) => {
8291
+ const d = toDate(v);
8292
+ return d ? formatRelativeTime(d, { style: "intl" }) : null;
8293
+ },
8294
+ parse: (raw) => raw === "" || raw == null ? null : String(raw)
8295
+ },
8296
+ // ── Structured ────────────────────────────────────────────────────────────
8297
+ {
8298
+ id: "json",
8299
+ label: "JSON",
8300
+ description: "Structured object",
8301
+ group: "Structured",
8302
+ base: "json",
8303
+ alsoAccepts: ["array"],
8304
+ editor: "json",
8305
+ format: (v) => {
8306
+ if (v === null || v === void 0) return null;
8307
+ if (typeof v === "object") return JSON.stringify(v);
8308
+ return toText(v);
8309
+ },
8310
+ parse: (raw) => {
8311
+ if (raw == null || raw === "") return null;
8312
+ if (typeof raw !== "string") return raw;
8313
+ try {
8314
+ return JSON.parse(raw);
8315
+ } catch {
8316
+ return raw;
8317
+ }
8318
+ }
8319
+ },
8320
+ {
8321
+ id: "array",
8322
+ label: "List",
8323
+ description: "List of values",
8324
+ group: "Structured",
8325
+ base: "array",
8326
+ alsoAccepts: ["json"],
8327
+ editor: "json",
8328
+ format: (v) => {
8329
+ const list = toList(v);
8330
+ return list === null ? null : list.map((i) => String(i)).join(", ");
8331
+ },
8332
+ parse: (raw) => {
8333
+ if (raw == null || raw === "") return null;
8334
+ if (Array.isArray(raw)) return raw;
8335
+ return toList(raw) ?? raw;
8336
+ }
8337
+ },
8338
+ {
8339
+ id: "tags",
8340
+ label: "Tags",
8341
+ description: "List of values shown as chips",
8342
+ group: "Structured",
8343
+ base: "array",
8344
+ alsoAccepts: ["json", "string"],
8345
+ editor: "json",
8346
+ rich: true,
8347
+ format: (v) => {
8348
+ const list = toList(v);
8349
+ return list === null ? null : list.map((i) => String(i)).join(", ");
8350
+ },
8351
+ parse: (raw) => {
8352
+ if (raw == null || raw === "") return null;
8353
+ if (Array.isArray(raw)) return raw;
8354
+ return toList(raw) ?? raw;
8355
+ }
8356
+ },
8357
+ // ─── Choice ────────────────────────────────────────────────────────────────
8358
+ //
8359
+ // An enum WITHOUT a database enum. The column stays `string` (or `array` for
8360
+ // multi), the database enforces nothing, and stripping the format leaves
8361
+ // every stored value exactly as it was. Options are a UI layer — the same
8362
+ // trick `percent` plays on a number.
8363
+ //
8364
+ // The fallback law is the whole reason this is safe to switch on over live
8365
+ // data: a value not in the option list is NOT an error and is NEVER blanked.
8366
+ // `format()` returns null for it, `<FormattedFieldValue>` renders it in amber
8367
+ // with the reason, and the user can fix it or adopt it. Declaring the options
8368
+ // is therefore how you FIND your stray values, not how you lose them.
8369
+ //
8370
+ // Options resolve through `choices.ts` — inline `options.choices`, or a
8371
+ // structured list via `options.structuredList`. This def only ever sees
8372
+ // whatever the caller resolved into `options.choices`, so it stays pure and
8373
+ // synchronous like every other format.
8374
+ {
8375
+ id: "choice",
8376
+ label: "Choice",
8377
+ description: "One value from a list of options",
8378
+ group: "Choice",
8379
+ base: "string",
8380
+ alsoAccepts: ["number", "integer", "boolean"],
8381
+ editor: "select",
8382
+ rich: true,
8383
+ optionKeys: ["choices", "structuredList", "allowOther"],
8384
+ format: (v, options) => {
8385
+ const text = toText(v);
8386
+ if (text === null) return null;
8387
+ const trimmed = text.trim();
8388
+ if (trimmed === "") return "";
8389
+ const match = findChoice(options.choices, trimmed);
8390
+ if (!options.choices || options.choices.length === 0) return trimmed;
8391
+ return match ? match.label ?? match.value : null;
8392
+ },
8393
+ parse: (raw) => {
8394
+ if (raw == null) return null;
8395
+ const text = toText(raw);
8396
+ if (text === null) return raw;
8397
+ const trimmed = text.trim();
8398
+ return trimmed === "" ? null : trimmed;
8399
+ }
8400
+ },
8401
+ {
8402
+ id: "multi_choice",
8403
+ label: "Multi-choice",
8404
+ description: "Any number of values from a list of options",
8405
+ group: "Choice",
8406
+ base: "array",
8407
+ alsoAccepts: ["string", "json"],
8408
+ editor: "multiselect",
8409
+ rich: true,
8410
+ optionKeys: ["choices", "structuredList", "allowOther"],
8411
+ format: (v, options) => {
8412
+ const list = toList(v);
8413
+ if (list === null) return null;
8414
+ if (list.length === 0) return "";
8415
+ const labels = [];
8416
+ let anyOffList = false;
8417
+ for (const entry of list) {
8418
+ const text = toText(entry);
8419
+ if (text === null) {
8420
+ anyOffList = true;
8421
+ continue;
8422
+ }
8423
+ const match = findChoice(options.choices, text.trim());
8424
+ if (match) labels.push(match.label ?? match.value);
8425
+ else {
8426
+ labels.push(text.trim());
8427
+ anyOffList = true;
8428
+ }
8429
+ }
8430
+ const haveOptions = !!options.choices && options.choices.length > 0;
8431
+ if (haveOptions && anyOffList) return null;
8432
+ return labels.join(", ");
8433
+ },
8434
+ parse: (raw) => {
8435
+ if (raw == null || raw === "") return null;
8436
+ if (Array.isArray(raw)) return raw;
8437
+ return toList(raw) ?? raw;
8438
+ }
8439
+ },
8440
+ // ─── Computed ──────────────────────────────────────────────────────────────
8441
+ //
8442
+ // A formula column stores NOTHING. `metadata.format.options.formula` holds
8443
+ // the expression; the stored cell is always null; the value is computed on
8444
+ // read from the other columns of the same row
8445
+ // (`features/data-tables/formulas.ts`). Grouped under Structured on purpose
8446
+ // — the picker's groups are a fixed vocabulary, and a formula is structure
8447
+ // over a plain string column, not a sixth family.
8448
+ //
8449
+ // `format()` here is handed the COMPUTED value, never a stored one, and its
8450
+ // only job is to render it: through `resultFormat`'s own `format()` when the
8451
+ // column declares one (a computed total shown as Currency, a computed date
8452
+ // shown as a Date), and plainly otherwise. It never returns null for an
8453
+ // empty value, because a formula legitimately produces BLANK.
8454
+ //
8455
+ // No `optionKeys`: the expression is authored in its own editor, not in the
8456
+ // generic option rail, and listing a key the picker has no control for would
8457
+ // open an empty options section under every formula column.
8458
+ {
8459
+ id: "formula",
8460
+ label: "Formula",
8461
+ description: "Computed from the other columns in the row \u2014 never typed in",
8462
+ group: "Structured",
8463
+ base: "string",
8464
+ editor: "computed",
8465
+ format: (v, o) => {
8466
+ const target = o.formula?.resultFormat;
8467
+ if (target && target !== "formula") {
8468
+ const delegate = FIELD_FORMATS[target];
8469
+ if (delegate) {
8470
+ const rendered = delegate.format(v, o);
8471
+ if (rendered !== null) return rendered;
8472
+ }
8473
+ }
8474
+ if (v === null || v === void 0) return "";
8475
+ if (typeof v === "boolean") return v ? "Yes" : "No";
8476
+ if (typeof v === "number") return groupedNumber(v, o);
8477
+ return toText(v);
8478
+ },
8479
+ // Nothing is ever stored in a formula column. Returning the raw input here
8480
+ // would be the one way a computed cell could acquire a value of its own.
8481
+ parse: () => null
8482
+ }
8483
+ ];
8484
+ var FIELD_FORMATS = Object.freeze(
8485
+ Object.fromEntries(DEFS.map((d) => [d.id, d]))
8486
+ );
8487
+ var FIELD_FORMAT_LIST = Object.freeze(DEFS);
8488
+ var FIELD_FORMAT_IDS = DEFS.map((d) => d.id);
8489
+ function getFieldFormat(id) {
8490
+ if (!id) return null;
8491
+ return FIELD_FORMATS[id] ?? null;
8492
+ }
8493
+ function defaultFormatForBase(base) {
8494
+ switch (base) {
8495
+ case "number":
8496
+ return "number";
8497
+ case "integer":
8498
+ return "integer";
8499
+ case "boolean":
8500
+ return "boolean";
8501
+ case "date":
8502
+ return "date";
8503
+ case "datetime":
8504
+ return "datetime";
8505
+ case "json":
8506
+ return "json";
8507
+ case "array":
8508
+ return "array";
8509
+ default:
8510
+ return "text";
8511
+ }
8512
+ }
8513
+
8514
+ // src/field-formats/format.ts
8515
+ function isEmpty(value) {
8516
+ return value === null || value === void 0 || value === "";
8517
+ }
8518
+ function baseText(value) {
8519
+ if (isEmpty(value)) return "";
8520
+ if (typeof value === "object") {
8521
+ try {
8522
+ return JSON.stringify(value);
8523
+ } catch {
8524
+ return String(value);
8525
+ }
8526
+ }
8527
+ return String(value);
8528
+ }
8529
+ function formatFieldValue(value, config, dataType) {
8530
+ if (isEmpty(value)) return { ok: true, text: "", empty: true };
8531
+ const def = config ? getFieldFormat(config.id) : null;
8532
+ const effective = def ?? FIELD_FORMATS[defaultFormatForBase(dataType ?? "string")];
8533
+ let formatted;
8534
+ try {
8535
+ formatted = effective.format(value, config?.options ?? {});
8536
+ } catch {
8537
+ formatted = null;
8538
+ }
8539
+ if (formatted !== null) return { ok: true, text: formatted, empty: false };
8540
+ return {
8541
+ ok: false,
8542
+ text: baseText(value),
8543
+ empty: false,
8544
+ reason: `This value is not a valid ${effective.label.toLowerCase()} \u2014 showing the stored value instead.`
8545
+ };
8546
+ }
8547
+
8548
+ // src/data-table/column-format.tsx
7540
8549
  import { jsx as jsx37, jsxs as jsxs27 } from "react/jsx-runtime";
8550
+ function formatColumnValue(col, value) {
8551
+ if (!col.format) return null;
8552
+ return formatFieldValue(value, col.format);
8553
+ }
8554
+ function alignForFormat(col) {
8555
+ if (col.align) return col.align;
8556
+ if (!col.format) return void 0;
8557
+ const def = getFieldFormat(col.format.id);
8558
+ if (!def) return void 0;
8559
+ return def.numericAlign ? "right" : void 0;
8560
+ }
8561
+ var FORMAT_MISMATCH_CLASS = "text-amber-600 underline decoration-dotted underline-offset-2 dark:text-amber-400";
8562
+ function FormattedCell({ result }) {
8563
+ if (result.empty) return /* @__PURE__ */ jsx37("span", { className: "text-muted-foreground", children: "\u2014" });
8564
+ if (result.ok) {
8565
+ return /* @__PURE__ */ jsx37("span", { className: "block truncate text-sm text-foreground", children: result.text });
8566
+ }
8567
+ return /* @__PURE__ */ jsxs27(Tooltip, { children: [
8568
+ /* @__PURE__ */ jsx37(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx37("span", { className: cn("block truncate text-sm", FORMAT_MISMATCH_CLASS), children: result.text }) }),
8569
+ /* @__PURE__ */ jsx37(TooltipContent, { className: "max-w-md whitespace-pre-wrap break-words", children: result.reason ?? "This value does not fit the format this column declares." })
8570
+ ] });
8571
+ }
8572
+
8573
+ // src/data-table/DirtySavePill.tsx
8574
+ import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
7541
8575
  function DirtySavePill({
7542
8576
  changeCount,
7543
8577
  saving,
@@ -7546,20 +8580,20 @@ function DirtySavePill({
7546
8580
  className
7547
8581
  }) {
7548
8582
  if (changeCount <= 0) return null;
7549
- return /* @__PURE__ */ jsx37(
8583
+ return /* @__PURE__ */ jsx38(
7550
8584
  "div",
7551
8585
  {
7552
8586
  className: cn(
7553
8587
  "pointer-events-none fixed inset-x-0 bottom-6 z-50 flex justify-center pb-safe",
7554
8588
  className
7555
8589
  ),
7556
- children: /* @__PURE__ */ jsxs27("div", { className: "pointer-events-auto flex items-center gap-2 rounded-full border border-border bg-card px-3 py-1.5 shadow-lg elevation-2", children: [
7557
- /* @__PURE__ */ jsxs27("span", { className: "px-1 text-xs font-medium text-muted-foreground", children: [
8590
+ children: /* @__PURE__ */ jsxs28("div", { className: "pointer-events-auto flex items-center gap-2 rounded-full border border-border bg-card px-3 py-1.5 shadow-lg elevation-2", children: [
8591
+ /* @__PURE__ */ jsxs28("span", { className: "px-1 text-xs font-medium text-muted-foreground", children: [
7558
8592
  changeCount,
7559
8593
  " unsaved change",
7560
8594
  changeCount === 1 ? "" : "s"
7561
8595
  ] }),
7562
- /* @__PURE__ */ jsxs27(
8596
+ /* @__PURE__ */ jsxs28(
7563
8597
  Button,
7564
8598
  {
7565
8599
  type: "button",
@@ -7569,12 +8603,12 @@ function DirtySavePill({
7569
8603
  disabled: saving,
7570
8604
  onClick: onCancel,
7571
8605
  children: [
7572
- /* @__PURE__ */ jsx37(X, { className: "h-3.5 w-3.5" }),
8606
+ /* @__PURE__ */ jsx38(X, { className: "h-3.5 w-3.5" }),
7573
8607
  "Cancel"
7574
8608
  ]
7575
8609
  }
7576
8610
  ),
7577
- /* @__PURE__ */ jsxs27(
8611
+ /* @__PURE__ */ jsxs28(
7578
8612
  Button,
7579
8613
  {
7580
8614
  type: "button",
@@ -7583,7 +8617,7 @@ function DirtySavePill({
7583
8617
  disabled: saving,
7584
8618
  onClick: onSave,
7585
8619
  children: [
7586
- saving ? /* @__PURE__ */ jsx37(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx37(Save, { className: "h-3.5 w-3.5" }),
8620
+ saving ? /* @__PURE__ */ jsx38(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx38(Save, { className: "h-3.5 w-3.5" }),
7587
8621
  "Save"
7588
8622
  ]
7589
8623
  }
@@ -7595,7 +8629,7 @@ function DirtySavePill({
7595
8629
 
7596
8630
  // src/data-table/EditableTableCell.tsx
7597
8631
  import { useEffect as useEffect14, useRef as useRef12, useState as useState19 } from "react";
7598
- import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
8632
+ import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
7599
8633
  function CellEditShell({
7600
8634
  href,
7601
8635
  display,
@@ -7604,8 +8638,8 @@ function CellEditShell({
7604
8638
  editButton
7605
8639
  }) {
7606
8640
  const { Link: HostLink } = useMatrxDataTableHost();
7607
- const Link = HostLink ?? ((props) => /* @__PURE__ */ jsx38("a", { ...props }));
7608
- return /* @__PURE__ */ jsxs28(
8641
+ const Link = HostLink ?? ((props) => /* @__PURE__ */ jsx39("a", { ...props }));
8642
+ return /* @__PURE__ */ jsxs29(
7609
8643
  "span",
7610
8644
  {
7611
8645
  className: cn(
@@ -7617,7 +8651,7 @@ function CellEditShell({
7617
8651
  className
7618
8652
  ),
7619
8653
  children: [
7620
- href ? /* @__PURE__ */ jsx38(
8654
+ href ? /* @__PURE__ */ jsx39(
7621
8655
  Link,
7622
8656
  {
7623
8657
  href,
@@ -7625,7 +8659,7 @@ function CellEditShell({
7625
8659
  className: "min-w-0 flex-1 overflow-hidden truncate rounded outline-none focus-visible:ring-2 focus-visible:ring-ring",
7626
8660
  children: display
7627
8661
  }
7628
- ) : /* @__PURE__ */ jsx38("span", { className: "block min-w-0 flex-1 overflow-hidden", children: display }),
8662
+ ) : /* @__PURE__ */ jsx39("span", { className: "block min-w-0 flex-1 overflow-hidden", children: display }),
7629
8663
  editButton
7630
8664
  ]
7631
8665
  }
@@ -7650,7 +8684,7 @@ function EditableTableCell({
7650
8684
  }, [editRequest]);
7651
8685
  const usePencil = Boolean(href) || editTrigger === "pencil";
7652
8686
  if (editType === "string") {
7653
- return /* @__PURE__ */ jsx38(
8687
+ return /* @__PURE__ */ jsx39(
7654
8688
  InlineStringEditor,
7655
8689
  {
7656
8690
  value: stringifyCellValue(value),
@@ -7664,30 +8698,30 @@ function EditableTableCell({
7664
8698
  }
7665
8699
  );
7666
8700
  }
7667
- return /* @__PURE__ */ jsxs28(Popover, { open, onOpenChange: setOpen, children: [
7668
- usePencil ? /* @__PURE__ */ jsx38(
8701
+ return /* @__PURE__ */ jsxs29(Popover, { open, onOpenChange: setOpen, children: [
8702
+ usePencil ? /* @__PURE__ */ jsx39(
7669
8703
  CellEditShell,
7670
8704
  {
7671
8705
  ...href === void 0 ? {} : { href },
7672
8706
  display,
7673
8707
  ...dirty === void 0 ? {} : { dirty },
7674
8708
  ...className === void 0 ? {} : { className },
7675
- editButton: /* @__PURE__ */ jsxs28(Tooltip, { children: [
7676
- /* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(
8709
+ editButton: /* @__PURE__ */ jsxs29(Tooltip, { children: [
8710
+ /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(
7677
8711
  "button",
7678
8712
  {
7679
8713
  type: "button",
7680
8714
  "aria-label": "Edit",
7681
8715
  onClick: (e) => e.stopPropagation(),
7682
8716
  className: CELL_PENCIL_CLASS,
7683
- children: /* @__PURE__ */ jsx38(Pencil, { className: "h-3 w-3" })
8717
+ children: /* @__PURE__ */ jsx39(Pencil, { className: "h-3 w-3" })
7684
8718
  }
7685
8719
  ) }) }),
7686
- /* @__PURE__ */ jsx38(TooltipContent, { children: "Edit" })
8720
+ /* @__PURE__ */ jsx39(TooltipContent, { children: "Edit" })
7687
8721
  ] })
7688
8722
  }
7689
- ) : /* @__PURE__ */ jsxs28(Tooltip, { children: [
7690
- /* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs28(
8723
+ ) : /* @__PURE__ */ jsxs29(Tooltip, { children: [
8724
+ /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs29(
7691
8725
  "button",
7692
8726
  {
7693
8727
  type: "button",
@@ -7698,20 +8732,20 @@ function EditableTableCell({
7698
8732
  className
7699
8733
  ),
7700
8734
  children: [
7701
- /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 overflow-hidden", children: display }),
7702
- editType === "select" ? /* @__PURE__ */ jsx38(ChevronDown, { className: "h-3 w-3 shrink-0 text-muted-foreground/70 transition-colors group-hover/cell-select:text-foreground" }) : null
8735
+ /* @__PURE__ */ jsx39("span", { className: "min-w-0 flex-1 overflow-hidden", children: display }),
8736
+ editType === "select" ? /* @__PURE__ */ jsx39(ChevronDown, { className: "h-3 w-3 shrink-0 text-muted-foreground/70 transition-colors group-hover/cell-select:text-foreground" }) : null
7703
8737
  ]
7704
8738
  }
7705
8739
  ) }) }),
7706
- /* @__PURE__ */ jsx38(TooltipContent, { children: "Edit value" })
8740
+ /* @__PURE__ */ jsx39(TooltipContent, { children: "Edit value" })
7707
8741
  ] }),
7708
- /* @__PURE__ */ jsx38(
8742
+ /* @__PURE__ */ jsx39(
7709
8743
  PopoverContent,
7710
8744
  {
7711
8745
  align: "start",
7712
8746
  className: "w-56 p-2",
7713
8747
  onClick: (e) => e.stopPropagation(),
7714
- children: /* @__PURE__ */ jsx38(
8748
+ children: /* @__PURE__ */ jsx39(
7715
8749
  TypedEditor,
7716
8750
  {
7717
8751
  editType,
@@ -7749,15 +8783,15 @@ function InlineStringEditor({
7749
8783
  }, [editRequest, value]);
7750
8784
  if (!editing) {
7751
8785
  if (usePencil) {
7752
- return /* @__PURE__ */ jsx38(
8786
+ return /* @__PURE__ */ jsx39(
7753
8787
  CellEditShell,
7754
8788
  {
7755
8789
  ...href === void 0 ? {} : { href },
7756
8790
  display,
7757
8791
  ...dirty === void 0 ? {} : { dirty },
7758
8792
  ...className === void 0 ? {} : { className },
7759
- editButton: /* @__PURE__ */ jsxs28(Tooltip, { children: [
7760
- /* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(
8793
+ editButton: /* @__PURE__ */ jsxs29(Tooltip, { children: [
8794
+ /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(
7761
8795
  "button",
7762
8796
  {
7763
8797
  type: "button",
@@ -7768,16 +8802,16 @@ function InlineStringEditor({
7768
8802
  setEditing(true);
7769
8803
  },
7770
8804
  className: CELL_PENCIL_CLASS,
7771
- children: /* @__PURE__ */ jsx38(Pencil, { className: "h-3 w-3" })
8805
+ children: /* @__PURE__ */ jsx39(Pencil, { className: "h-3 w-3" })
7772
8806
  }
7773
8807
  ) }),
7774
- /* @__PURE__ */ jsx38(TooltipContent, { children: "Edit" })
8808
+ /* @__PURE__ */ jsx39(TooltipContent, { children: "Edit" })
7775
8809
  ] })
7776
8810
  }
7777
8811
  );
7778
8812
  }
7779
- return /* @__PURE__ */ jsxs28(Tooltip, { children: [
7780
- /* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(
8813
+ return /* @__PURE__ */ jsxs29(Tooltip, { children: [
8814
+ /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(
7781
8815
  "button",
7782
8816
  {
7783
8817
  type: "button",
@@ -7794,10 +8828,10 @@ function InlineStringEditor({
7794
8828
  children: display
7795
8829
  }
7796
8830
  ) }),
7797
- /* @__PURE__ */ jsx38(TooltipContent, { children: "Click to edit" })
8831
+ /* @__PURE__ */ jsx39(TooltipContent, { children: "Click to edit" })
7798
8832
  ] });
7799
8833
  }
7800
- return /* @__PURE__ */ jsx38(
8834
+ return /* @__PURE__ */ jsx39(
7801
8835
  Input,
7802
8836
  {
7803
8837
  autoFocus: true,
@@ -7833,9 +8867,9 @@ function TypedEditor({
7833
8867
  }) {
7834
8868
  if (editType === "boolean") {
7835
8869
  const checked = Boolean(value);
7836
- return /* @__PURE__ */ jsxs28("div", { className: "flex items-center justify-between gap-2", children: [
7837
- /* @__PURE__ */ jsx38("span", { className: "text-xs font-medium", children: "Value" }),
7838
- /* @__PURE__ */ jsx38(
8870
+ return /* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-between gap-2", children: [
8871
+ /* @__PURE__ */ jsx39("span", { className: "text-xs font-medium", children: "Value" }),
8872
+ /* @__PURE__ */ jsx39(
7839
8873
  Checkbox,
7840
8874
  {
7841
8875
  checked,
@@ -7845,7 +8879,7 @@ function TypedEditor({
7845
8879
  ] });
7846
8880
  }
7847
8881
  if (editType === "number") {
7848
- return /* @__PURE__ */ jsx38(
8882
+ return /* @__PURE__ */ jsx39(
7849
8883
  NumberEditor,
7850
8884
  {
7851
8885
  value: typeof value === "number" ? value : Number(value) || 0,
@@ -7855,7 +8889,7 @@ function TypedEditor({
7855
8889
  );
7856
8890
  }
7857
8891
  if (editType === "tags") {
7858
- return /* @__PURE__ */ jsx38(
8892
+ return /* @__PURE__ */ jsx39(
7859
8893
  TagsEditor,
7860
8894
  {
7861
8895
  value: Array.isArray(value) ? value.map(String) : [],
@@ -7866,19 +8900,19 @@ function TypedEditor({
7866
8900
  );
7867
8901
  }
7868
8902
  if (editType === "select") {
7869
- return /* @__PURE__ */ jsxs28(
8903
+ return /* @__PURE__ */ jsxs29(
7870
8904
  Select,
7871
8905
  {
7872
8906
  value: stringifyCellValue(value),
7873
8907
  onValueChange: (v) => onCommit(v),
7874
8908
  children: [
7875
- /* @__PURE__ */ jsx38(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx38(SelectValue, {}) }),
7876
- /* @__PURE__ */ jsx38(SelectContent, { children: editOptions.map((o) => /* @__PURE__ */ jsx38(SelectItem, { value: o.value, children: o.label }, o.value)) })
8909
+ /* @__PURE__ */ jsx39(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx39(SelectValue, {}) }),
8910
+ /* @__PURE__ */ jsx39(SelectContent, { children: editOptions.map((o) => /* @__PURE__ */ jsx39(SelectItem, { value: o.value, children: o.label }, o.value)) })
7877
8911
  ]
7878
8912
  }
7879
8913
  );
7880
8914
  }
7881
- return /* @__PURE__ */ jsx38(
8915
+ return /* @__PURE__ */ jsx39(
7882
8916
  Input,
7883
8917
  {
7884
8918
  type: "date",
@@ -7908,11 +8942,11 @@ function TagsEditor({
7908
8942
  const matches = suggestions.filter(
7909
8943
  (s) => !tags.includes(s.value) && s.value !== "__none__" && (!draft || s.label.toLowerCase().includes(draft.trim().toLowerCase()))
7910
8944
  ).slice(0, 6);
7911
- return /* @__PURE__ */ jsxs28("div", { className: "space-y-2", onClick: (e) => e.stopPropagation(), children: [
7912
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-wrap gap-1", children: [
7913
- tags.length === 0 && /* @__PURE__ */ jsx38("span", { className: "text-xs text-muted-foreground", children: "No tags" }),
7914
- tags.map((tag) => /* @__PURE__ */ jsxs28(Tooltip, { children: [
7915
- /* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs28(
8945
+ return /* @__PURE__ */ jsxs29("div", { className: "space-y-2", onClick: (e) => e.stopPropagation(), children: [
8946
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-wrap gap-1", children: [
8947
+ tags.length === 0 && /* @__PURE__ */ jsx39("span", { className: "text-xs text-muted-foreground", children: "No tags" }),
8948
+ tags.map((tag) => /* @__PURE__ */ jsxs29(Tooltip, { children: [
8949
+ /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs29(
7916
8950
  "button",
7917
8951
  {
7918
8952
  type: "button",
@@ -7921,17 +8955,17 @@ function TagsEditor({
7921
8955
  className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-0.5 text-[11px] hover:border-destructive hover:text-destructive",
7922
8956
  children: [
7923
8957
  tag,
7924
- /* @__PURE__ */ jsx38(X, { className: "h-2.5 w-2.5" })
8958
+ /* @__PURE__ */ jsx39(X, { className: "h-2.5 w-2.5" })
7925
8959
  ]
7926
8960
  }
7927
8961
  ) }),
7928
- /* @__PURE__ */ jsxs28(TooltipContent, { children: [
8962
+ /* @__PURE__ */ jsxs29(TooltipContent, { children: [
7929
8963
  "Remove ",
7930
8964
  tag
7931
8965
  ] })
7932
8966
  ] }, tag))
7933
8967
  ] }),
7934
- /* @__PURE__ */ jsx38(
8968
+ /* @__PURE__ */ jsx39(
7935
8969
  Input,
7936
8970
  {
7937
8971
  autoFocus: true,
@@ -7952,7 +8986,7 @@ function TagsEditor({
7952
8986
  className: "h-8 text-xs"
7953
8987
  }
7954
8988
  ),
7955
- matches.length > 0 && /* @__PURE__ */ jsx38("div", { className: "flex flex-wrap gap-1", children: matches.map((s) => /* @__PURE__ */ jsxs28(
8989
+ matches.length > 0 && /* @__PURE__ */ jsx39("div", { className: "flex flex-wrap gap-1", children: matches.map((s) => /* @__PURE__ */ jsxs29(
7956
8990
  "button",
7957
8991
  {
7958
8992
  type: "button",
@@ -7965,8 +8999,8 @@ function TagsEditor({
7965
8999
  },
7966
9000
  s.value
7967
9001
  )) }),
7968
- /* @__PURE__ */ jsxs28("div", { className: "flex justify-end gap-1 pt-1", children: [
7969
- /* @__PURE__ */ jsx38(
9002
+ /* @__PURE__ */ jsxs29("div", { className: "flex justify-end gap-1 pt-1", children: [
9003
+ /* @__PURE__ */ jsx39(
7970
9004
  Button,
7971
9005
  {
7972
9006
  size: "sm",
@@ -7974,17 +9008,17 @@ function TagsEditor({
7974
9008
  className: "h-7 px-2",
7975
9009
  "aria-label": "Cancel edit",
7976
9010
  onClick: onCancel,
7977
- children: /* @__PURE__ */ jsx38(X, { className: "h-3.5 w-3.5" })
9011
+ children: /* @__PURE__ */ jsx39(X, { className: "h-3.5 w-3.5" })
7978
9012
  }
7979
9013
  ),
7980
- /* @__PURE__ */ jsx38(
9014
+ /* @__PURE__ */ jsx39(
7981
9015
  Button,
7982
9016
  {
7983
9017
  size: "sm",
7984
9018
  className: "h-7 px-2",
7985
9019
  "aria-label": "Apply tags",
7986
9020
  onClick: () => onCommit(tags),
7987
- children: /* @__PURE__ */ jsx38(Check, { className: "h-3.5 w-3.5" })
9021
+ children: /* @__PURE__ */ jsx39(Check, { className: "h-3.5 w-3.5" })
7988
9022
  }
7989
9023
  )
7990
9024
  ] })
@@ -7996,8 +9030,8 @@ function NumberEditor({
7996
9030
  onCancel
7997
9031
  }) {
7998
9032
  const [draft, setDraft] = useState19(String(value));
7999
- return /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-2", children: [
8000
- /* @__PURE__ */ jsx38(
9033
+ return /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-2", children: [
9034
+ /* @__PURE__ */ jsx39(
8001
9035
  Input,
8002
9036
  {
8003
9037
  autoFocus: true,
@@ -8014,8 +9048,8 @@ function NumberEditor({
8014
9048
  }
8015
9049
  }
8016
9050
  ),
8017
- /* @__PURE__ */ jsxs28("div", { className: "flex justify-end gap-1", children: [
8018
- /* @__PURE__ */ jsx38(
9051
+ /* @__PURE__ */ jsxs29("div", { className: "flex justify-end gap-1", children: [
9052
+ /* @__PURE__ */ jsx39(
8019
9053
  Button,
8020
9054
  {
8021
9055
  type: "button",
@@ -8024,10 +9058,10 @@ function NumberEditor({
8024
9058
  className: "h-7",
8025
9059
  "aria-label": "Cancel edit",
8026
9060
  onClick: onCancel,
8027
- children: /* @__PURE__ */ jsx38(X, { className: "h-3.5 w-3.5" })
9061
+ children: /* @__PURE__ */ jsx39(X, { className: "h-3.5 w-3.5" })
8028
9062
  }
8029
9063
  ),
8030
- /* @__PURE__ */ jsx38(
9064
+ /* @__PURE__ */ jsx39(
8031
9065
  Button,
8032
9066
  {
8033
9067
  type: "button",
@@ -8038,7 +9072,7 @@ function NumberEditor({
8038
9072
  const n = Number(draft);
8039
9073
  if (Number.isFinite(n)) onCommit(n);
8040
9074
  },
8041
- children: /* @__PURE__ */ jsx38(Check, { className: "h-3.5 w-3.5" })
9075
+ children: /* @__PURE__ */ jsx39(Check, { className: "h-3.5 w-3.5" })
8042
9076
  }
8043
9077
  )
8044
9078
  ] })
@@ -8046,24 +9080,24 @@ function NumberEditor({
8046
9080
  }
8047
9081
 
8048
9082
  // src/data-table/ToolbarFacets.tsx
8049
- import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
9083
+ import { jsx as jsx40, jsxs as jsxs30 } from "react/jsx-runtime";
8050
9084
  function ToolbarFacets({ facets }) {
8051
9085
  if (facets.length === 0) return null;
8052
- return /* @__PURE__ */ jsx39("div", { className: "flex flex-wrap items-center gap-2", children: facets.map((facet) => {
9086
+ return /* @__PURE__ */ jsx40("div", { className: "flex flex-wrap items-center gap-2", children: facets.map((facet) => {
8053
9087
  if (facet.type === "custom") {
8054
- return /* @__PURE__ */ jsx39("div", { children: facet.render() }, facet.id);
9088
+ return /* @__PURE__ */ jsx40("div", { children: facet.render() }, facet.id);
8055
9089
  }
8056
9090
  const defaultValue = facet.defaultValue ?? facet.options[0]?.value ?? "";
8057
9091
  const isNonDefault = facet.value !== defaultValue;
8058
- return /* @__PURE__ */ jsxs29(
9092
+ return /* @__PURE__ */ jsxs30(
8059
9093
  "div",
8060
9094
  {
8061
9095
  className: "flex flex-wrap items-center gap-1.5 max-sm:grid max-sm:w-full max-sm:grid-cols-3",
8062
9096
  children: [
8063
- facet.label ? /* @__PURE__ */ jsx39("span", { className: "mr-0.5 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: facet.label }) : null,
9097
+ facet.label ? /* @__PURE__ */ jsx40("span", { className: "mr-0.5 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: facet.label }) : null,
8064
9098
  facet.options.map((opt) => {
8065
9099
  const active = facet.value === opt.value;
8066
- return /* @__PURE__ */ jsxs29(
9100
+ return /* @__PURE__ */ jsxs30(
8067
9101
  Button,
8068
9102
  {
8069
9103
  type: "button",
@@ -8077,8 +9111,8 @@ function ToolbarFacets({ facets }) {
8077
9111
  children: [
8078
9112
  opt.icon,
8079
9113
  opt.label,
8080
- active && isNonDefault ? /* @__PURE__ */ jsx39(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs29(Tooltip, { children: [
8081
- /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(
9114
+ active && isNonDefault ? /* @__PURE__ */ jsx40(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs30(Tooltip, { children: [
9115
+ /* @__PURE__ */ jsx40(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx40(
8082
9116
  "span",
8083
9117
  {
8084
9118
  role: "button",
@@ -8096,10 +9130,10 @@ function ToolbarFacets({ facets }) {
8096
9130
  facet.onChange(defaultValue);
8097
9131
  }
8098
9132
  },
8099
- children: /* @__PURE__ */ jsx39(X, { className: "h-3 w-3" })
9133
+ children: /* @__PURE__ */ jsx40(X, { className: "h-3 w-3" })
8100
9134
  }
8101
9135
  ) }),
8102
- /* @__PURE__ */ jsx39(TooltipContent, { side: "top", children: "Clear this filter" })
9136
+ /* @__PURE__ */ jsx40(TooltipContent, { side: "top", children: "Clear this filter" })
8103
9137
  ] }) }) : null
8104
9138
  ]
8105
9139
  },
@@ -8126,7 +9160,7 @@ function resetToolbarFacets(facets) {
8126
9160
 
8127
9161
  // src/data-table/LayeredFilterBuilder.tsx
8128
9162
  import { useState as useState20 } from "react";
8129
- import { Fragment as Fragment5, jsx as jsx40, jsxs as jsxs30 } from "react/jsx-runtime";
9163
+ import { Fragment as Fragment5, jsx as jsx41, jsxs as jsxs31 } from "react/jsx-runtime";
8130
9164
  function moveRule(rules, from, to) {
8131
9165
  if (from === to || to < 0 || to >= rules.length) return [...rules];
8132
9166
  const next = [...rules];
@@ -8172,8 +9206,8 @@ function LayeredFilterBuilder({
8172
9206
  const reorder = (from, to) => {
8173
9207
  onChange(moveRule(rules, from, to));
8174
9208
  };
8175
- return /* @__PURE__ */ jsxs30("div", { className: "flex min-w-0 flex-wrap items-center gap-1", children: [
8176
- /* @__PURE__ */ jsxs30(
9209
+ return /* @__PURE__ */ jsxs31("div", { className: "flex min-w-0 flex-wrap items-center gap-1", children: [
9210
+ /* @__PURE__ */ jsxs31(
8177
9211
  Popover,
8178
9212
  {
8179
9213
  open,
@@ -8185,7 +9219,7 @@ function LayeredFilterBuilder({
8185
9219
  }
8186
9220
  },
8187
9221
  children: [
8188
- /* @__PURE__ */ jsx40(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs30(
9222
+ /* @__PURE__ */ jsx41(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs31(
8189
9223
  Button,
8190
9224
  {
8191
9225
  type: "button",
@@ -8194,25 +9228,25 @@ function LayeredFilterBuilder({
8194
9228
  className: "h-8 gap-1.5 px-2 text-xs",
8195
9229
  "aria-label": label,
8196
9230
  children: [
8197
- /* @__PURE__ */ jsx40(SlidersHorizontal, { className: "h-3.5 w-3.5" }),
8198
- /* @__PURE__ */ jsx40("span", { className: "hidden sm:inline", children: rules.length > 0 ? `${rules.length} layers` : "Advanced" }),
8199
- rules.length > 0 ? /* @__PURE__ */ jsx40("span", { className: "sm:hidden", children: rules.length }) : null
9231
+ /* @__PURE__ */ jsx41(SlidersHorizontal, { className: "h-3.5 w-3.5" }),
9232
+ /* @__PURE__ */ jsx41("span", { className: "hidden sm:inline", children: rules.length > 0 ? `${rules.length} layers` : "Advanced" }),
9233
+ rules.length > 0 ? /* @__PURE__ */ jsx41("span", { className: "sm:hidden", children: rules.length }) : null
8200
9234
  ]
8201
9235
  }
8202
9236
  ) }),
8203
- /* @__PURE__ */ jsxs30(
9237
+ /* @__PURE__ */ jsxs31(
8204
9238
  PopoverContent,
8205
9239
  {
8206
9240
  align: "start",
8207
9241
  sideOffset: 6,
8208
9242
  className: "w-[min(46rem,calc(100vw-1rem))] p-0",
8209
9243
  children: [
8210
- /* @__PURE__ */ jsxs30("div", { className: "flex items-start justify-between gap-3 border-b border-border px-3 py-2.5", children: [
8211
- /* @__PURE__ */ jsxs30("div", { children: [
8212
- /* @__PURE__ */ jsx40("p", { className: "text-sm font-semibold text-foreground", children: "Narrow these results" }),
8213
- /* @__PURE__ */ jsx40("p", { className: "text-xs text-muted-foreground", children: "Every layer must match. Drag layers to put them in the order that makes sense to you." })
9244
+ /* @__PURE__ */ jsxs31("div", { className: "flex items-start justify-between gap-3 border-b border-border px-3 py-2.5", children: [
9245
+ /* @__PURE__ */ jsxs31("div", { children: [
9246
+ /* @__PURE__ */ jsx41("p", { className: "text-sm font-semibold text-foreground", children: "Narrow these results" }),
9247
+ /* @__PURE__ */ jsx41("p", { className: "text-xs text-muted-foreground", children: "Every layer must match. Drag layers to put them in the order that makes sense to you." })
8214
9248
  ] }),
8215
- rules.length > 0 ? /* @__PURE__ */ jsx40(
9249
+ rules.length > 0 ? /* @__PURE__ */ jsx41(
8216
9250
  Button,
8217
9251
  {
8218
9252
  type: "button",
@@ -8224,10 +9258,10 @@ function LayeredFilterBuilder({
8224
9258
  }
8225
9259
  ) : null
8226
9260
  ] }),
8227
- /* @__PURE__ */ jsx40("div", { className: "max-h-[min(28rem,65dvh)] space-y-1.5 overflow-y-auto p-2.5 scrollbar-thin", children: rules.length === 0 ? /* @__PURE__ */ jsxs30("div", { className: "rounded-md border border-dashed border-border px-3 py-5 text-center", children: [
8228
- /* @__PURE__ */ jsx40("p", { className: "text-sm font-medium text-foreground", children: "Start with one simple layer" }),
8229
- /* @__PURE__ */ jsx40("p", { className: "mt-1 text-xs text-muted-foreground", children: "For example: Keyword contains ITAD, then Keyword doesn't have the word \u201Cwhat\u201D." })
8230
- ] }) : rules.map((rule, index) => /* @__PURE__ */ jsx40(
9261
+ /* @__PURE__ */ jsx41("div", { className: "max-h-[min(28rem,65dvh)] space-y-1.5 overflow-y-auto p-2.5 scrollbar-thin", children: rules.length === 0 ? /* @__PURE__ */ jsxs31("div", { className: "rounded-md border border-dashed border-border px-3 py-5 text-center", children: [
9262
+ /* @__PURE__ */ jsx41("p", { className: "text-sm font-medium text-foreground", children: "Start with one simple layer" }),
9263
+ /* @__PURE__ */ jsx41("p", { className: "mt-1 text-xs text-muted-foreground", children: "For example: Keyword contains ITAD, then Keyword doesn't have the word \u201Cwhat\u201D." })
9264
+ ] }) : rules.map((rule, index) => /* @__PURE__ */ jsx41(
8231
9265
  LayeredRuleRow,
8232
9266
  {
8233
9267
  index,
@@ -8247,9 +9281,9 @@ function LayeredFilterBuilder({
8247
9281
  },
8248
9282
  rule.id
8249
9283
  )) }),
8250
- /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-2 border-t border-border px-3 py-2", children: [
8251
- /* @__PURE__ */ jsx40("p", { className: "text-[11px] text-muted-foreground", children: "The regular search still works and is applied before these layers." }),
8252
- /* @__PURE__ */ jsxs30(
9284
+ /* @__PURE__ */ jsxs31("div", { className: "flex items-center justify-between gap-2 border-t border-border px-3 py-2", children: [
9285
+ /* @__PURE__ */ jsx41("p", { className: "text-[11px] text-muted-foreground", children: "The regular search still works and is applied before these layers." }),
9286
+ /* @__PURE__ */ jsxs31(
8253
9287
  Button,
8254
9288
  {
8255
9289
  type: "button",
@@ -8259,7 +9293,7 @@ function LayeredFilterBuilder({
8259
9293
  disabled: rules.length >= maxRules,
8260
9294
  onClick: addRule,
8261
9295
  children: [
8262
- /* @__PURE__ */ jsx40(Plus, { className: "h-3.5 w-3.5" }),
9296
+ /* @__PURE__ */ jsx41(Plus, { className: "h-3.5 w-3.5" }),
8263
9297
  " Add layer"
8264
9298
  ]
8265
9299
  }
@@ -8271,7 +9305,7 @@ function LayeredFilterBuilder({
8271
9305
  ]
8272
9306
  }
8273
9307
  ),
8274
- rules.map((rule, index) => /* @__PURE__ */ jsxs30(
9308
+ rules.map((rule, index) => /* @__PURE__ */ jsxs31(
8275
9309
  "span",
8276
9310
  {
8277
9311
  className: cn(
@@ -8279,7 +9313,7 @@ function LayeredFilterBuilder({
8279
9313
  isCompleteLayeredFilterRule(rule) ? "border-border bg-muted/50 text-foreground" : "border-dashed border-warning/50 bg-warning/10 text-warning"
8280
9314
  ),
8281
9315
  children: [
8282
- /* @__PURE__ */ jsxs30(
9316
+ /* @__PURE__ */ jsxs31(
8283
9317
  "button",
8284
9318
  {
8285
9319
  type: "button",
@@ -8287,19 +9321,19 @@ function LayeredFilterBuilder({
8287
9321
  onClick: () => setOpen(true),
8288
9322
  title: isCompleteLayeredFilterRule(rule) ? layeredFilterRuleSummary(rule, fields) : `Layer ${index + 1} needs a value`,
8289
9323
  children: [
8290
- /* @__PURE__ */ jsx40("span", { className: "mr-1 text-muted-foreground", children: index + 1 }),
9324
+ /* @__PURE__ */ jsx41("span", { className: "mr-1 text-muted-foreground", children: index + 1 }),
8291
9325
  isCompleteLayeredFilterRule(rule) ? layeredFilterRuleSummary(rule, fields) : "Choose a value"
8292
9326
  ]
8293
9327
  }
8294
9328
  ),
8295
- /* @__PURE__ */ jsx40(
9329
+ /* @__PURE__ */ jsx41(
8296
9330
  "button",
8297
9331
  {
8298
9332
  type: "button",
8299
9333
  className: "shrink-0 rounded-full p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
8300
9334
  "aria-label": `Remove filter layer ${index + 1}`,
8301
9335
  onClick: () => removeRule(index),
8302
- children: /* @__PURE__ */ jsx40(X, { className: "h-3 w-3" })
9336
+ children: /* @__PURE__ */ jsx41(X, { className: "h-3 w-3" })
8303
9337
  }
8304
9338
  )
8305
9339
  ]
@@ -8329,7 +9363,7 @@ function LayeredRuleRow({
8329
9363
  event.preventDefault();
8330
9364
  onKeyboardMove(event.key === "ArrowUp" ? -1 : 1);
8331
9365
  };
8332
- return /* @__PURE__ */ jsxs30(
9366
+ return /* @__PURE__ */ jsxs31(
8333
9367
  "div",
8334
9368
  {
8335
9369
  className: cn(
@@ -8342,7 +9376,7 @@ function LayeredRuleRow({
8342
9376
  onDrop(index);
8343
9377
  },
8344
9378
  children: [
8345
- /* @__PURE__ */ jsx40(
9379
+ /* @__PURE__ */ jsx41(
8346
9380
  "button",
8347
9381
  {
8348
9382
  type: "button",
@@ -8356,10 +9390,10 @@ function LayeredRuleRow({
8356
9390
  },
8357
9391
  onDragEnd,
8358
9392
  onKeyDown: handleMoveKey,
8359
- children: /* @__PURE__ */ jsx40(GripVertical, { className: "h-3.5 w-3.5" })
9393
+ children: /* @__PURE__ */ jsx41(GripVertical, { className: "h-3.5 w-3.5" })
8360
9394
  }
8361
9395
  ),
8362
- /* @__PURE__ */ jsxs30(
9396
+ /* @__PURE__ */ jsxs31(
8363
9397
  Select,
8364
9398
  {
8365
9399
  value: field.id,
@@ -8377,16 +9411,16 @@ function LayeredRuleRow({
8377
9411
  });
8378
9412
  },
8379
9413
  children: [
8380
- /* @__PURE__ */ jsx40(
9414
+ /* @__PURE__ */ jsx41(
8381
9415
  SelectTrigger,
8382
9416
  {
8383
9417
  size: "sm",
8384
9418
  className: "h-7 w-full text-xs max-sm:col-span-1",
8385
9419
  "aria-label": `Filter layer ${index + 1} field`,
8386
- children: /* @__PURE__ */ jsx40(SelectValue, {})
9420
+ children: /* @__PURE__ */ jsx41(SelectValue, {})
8387
9421
  }
8388
9422
  ),
8389
- /* @__PURE__ */ jsx40(SelectContent, { children: fields.map((candidate) => /* @__PURE__ */ jsx40(
9423
+ /* @__PURE__ */ jsx41(SelectContent, { children: fields.map((candidate) => /* @__PURE__ */ jsx41(
8390
9424
  SelectItem,
8391
9425
  {
8392
9426
  value: candidate.id,
@@ -8398,7 +9432,7 @@ function LayeredRuleRow({
8398
9432
  ]
8399
9433
  }
8400
9434
  ),
8401
- /* @__PURE__ */ jsxs30(
9435
+ /* @__PURE__ */ jsxs31(
8402
9436
  Select,
8403
9437
  {
8404
9438
  value: rule.operator,
@@ -8410,35 +9444,35 @@ function LayeredRuleRow({
8410
9444
  });
8411
9445
  },
8412
9446
  children: [
8413
- /* @__PURE__ */ jsx40(
9447
+ /* @__PURE__ */ jsx41(
8414
9448
  SelectTrigger,
8415
9449
  {
8416
9450
  size: "sm",
8417
9451
  className: "h-7 w-full text-xs max-sm:col-start-2",
8418
9452
  "aria-label": `Filter layer ${index + 1} operator`,
8419
- children: /* @__PURE__ */ jsx40(SelectValue, {})
9453
+ children: /* @__PURE__ */ jsx41(SelectValue, {})
8420
9454
  }
8421
9455
  ),
8422
- /* @__PURE__ */ jsx40(SelectContent, { children: operators.map((operator) => /* @__PURE__ */ jsx40(SelectItem, { value: operator, className: "text-xs", children: LAYERED_FILTER_OPERATOR_LABELS[operator] }, operator)) })
9456
+ /* @__PURE__ */ jsx41(SelectContent, { children: operators.map((operator) => /* @__PURE__ */ jsx41(SelectItem, { value: operator, className: "text-xs", children: LAYERED_FILTER_OPERATOR_LABELS[operator] }, operator)) })
8423
9457
  ]
8424
9458
  }
8425
9459
  ),
8426
- /* @__PURE__ */ jsx40("div", { className: "min-w-0 max-sm:col-span-3 max-sm:col-start-1", children: !needsValue ? /* @__PURE__ */ jsx40("span", { className: "flex h-7 items-center px-2 text-xs text-muted-foreground", children: "No value needed" }) : field.kind === "select" ? /* @__PURE__ */ jsxs30(
9460
+ /* @__PURE__ */ jsx41("div", { className: "min-w-0 max-sm:col-span-3 max-sm:col-start-1", children: !needsValue ? /* @__PURE__ */ jsx41("span", { className: "flex h-7 items-center px-2 text-xs text-muted-foreground", children: "No value needed" }) : field.kind === "select" ? /* @__PURE__ */ jsxs31(
8427
9461
  Select,
8428
9462
  {
8429
9463
  value: rule.value,
8430
9464
  onValueChange: (value) => onChange({ value }),
8431
9465
  children: [
8432
- /* @__PURE__ */ jsx40(
9466
+ /* @__PURE__ */ jsx41(
8433
9467
  SelectTrigger,
8434
9468
  {
8435
9469
  size: "sm",
8436
9470
  className: "h-7 w-full text-xs",
8437
9471
  "aria-label": `Filter layer ${index + 1} value`,
8438
- children: /* @__PURE__ */ jsx40(SelectValue, {})
9472
+ children: /* @__PURE__ */ jsx41(SelectValue, {})
8439
9473
  }
8440
9474
  ),
8441
- /* @__PURE__ */ jsx40(SelectContent, { children: field.options.map((option) => /* @__PURE__ */ jsx40(
9475
+ /* @__PURE__ */ jsx41(SelectContent, { children: field.options.map((option) => /* @__PURE__ */ jsx41(
8442
9476
  SelectItem,
8443
9477
  {
8444
9478
  value: option.value,
@@ -8449,8 +9483,8 @@ function LayeredRuleRow({
8449
9483
  )) })
8450
9484
  ]
8451
9485
  }
8452
- ) : /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-1", children: [
8453
- /* @__PURE__ */ jsx40(
9486
+ ) : /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-1", children: [
9487
+ /* @__PURE__ */ jsx41(
8454
9488
  Input,
8455
9489
  {
8456
9490
  value: rule.value,
@@ -8461,9 +9495,9 @@ function LayeredRuleRow({
8461
9495
  "aria-label": `Filter layer ${index + 1} value`
8462
9496
  }
8463
9497
  ),
8464
- rule.operator === "between" ? /* @__PURE__ */ jsxs30(Fragment5, { children: [
8465
- /* @__PURE__ */ jsx40("span", { className: "text-[11px] text-muted-foreground", children: "and" }),
8466
- /* @__PURE__ */ jsx40(
9498
+ rule.operator === "between" ? /* @__PURE__ */ jsxs31(Fragment5, { children: [
9499
+ /* @__PURE__ */ jsx41("span", { className: "text-[11px] text-muted-foreground", children: "and" }),
9500
+ /* @__PURE__ */ jsx41(
8467
9501
  Input,
8468
9502
  {
8469
9503
  value: rule.valueTo ?? "",
@@ -8476,7 +9510,7 @@ function LayeredRuleRow({
8476
9510
  )
8477
9511
  ] }) : null
8478
9512
  ] }) }),
8479
- /* @__PURE__ */ jsx40(
9513
+ /* @__PURE__ */ jsx41(
8480
9514
  Button,
8481
9515
  {
8482
9516
  type: "button",
@@ -8485,7 +9519,7 @@ function LayeredRuleRow({
8485
9519
  className: "h-7 w-7 p-0 text-muted-foreground hover:text-destructive max-sm:col-start-3 max-sm:row-start-1",
8486
9520
  "aria-label": `Remove filter layer ${index + 1}`,
8487
9521
  onClick: onRemove,
8488
- children: /* @__PURE__ */ jsx40(Trash2, { className: "h-3.5 w-3.5" })
9522
+ children: /* @__PURE__ */ jsx41(Trash2, { className: "h-3.5 w-3.5" })
8489
9523
  }
8490
9524
  )
8491
9525
  ]
@@ -8598,7 +9632,7 @@ function safeQueryPage(requestedPage, totalItems, pageSize) {
8598
9632
  }
8599
9633
 
8600
9634
  // src/data-table/MatrxDataTable.tsx
8601
- import { Fragment as Fragment7, jsx as jsx41, jsxs as jsxs31 } from "react/jsx-runtime";
9635
+ import { Fragment as Fragment7, jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
8602
9636
  function TableToolbarAction({
8603
9637
  HostAction,
8604
9638
  ariaLabel,
@@ -8609,10 +9643,10 @@ function TableToolbarAction({
8609
9643
  children
8610
9644
  }) {
8611
9645
  if (HostAction) {
8612
- return /* @__PURE__ */ jsx41("span", { "data-matrx-table-toolbar-action": true, children: /* @__PURE__ */ jsx41(HostAction, { ariaLabel, tooltip, disabled, busy, onClick, children }) });
9646
+ return /* @__PURE__ */ jsx42("span", { "data-matrx-table-toolbar-action": true, children: /* @__PURE__ */ jsx42(HostAction, { ariaLabel, tooltip, disabled, busy, onClick, children }) });
8613
9647
  }
8614
- return /* @__PURE__ */ jsxs31(Tooltip, { children: [
8615
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41("span", { "data-matrx-table-toolbar-action": true, className: "inline-flex", children: /* @__PURE__ */ jsx41(
9648
+ return /* @__PURE__ */ jsxs32(Tooltip, { children: [
9649
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42("span", { "data-matrx-table-toolbar-action": true, className: "inline-flex", children: /* @__PURE__ */ jsx42(
8616
9650
  Button,
8617
9651
  {
8618
9652
  type: "button",
@@ -8627,7 +9661,7 @@ function TableToolbarAction({
8627
9661
  children: isValidElement2(children) ? cloneElement2(children, { className: cn("h-5 w-5", children.props.className) }) : children
8628
9662
  }
8629
9663
  ) }) }),
8630
- /* @__PURE__ */ jsx41(TooltipContent, { children: tooltip ?? ariaLabel })
9664
+ /* @__PURE__ */ jsx42(TooltipContent, { children: tooltip ?? ariaLabel })
8631
9665
  ] });
8632
9666
  }
8633
9667
  function hasSameRowReferences(previous, next) {
@@ -8644,7 +9678,7 @@ function TableRowCopyControl({
8644
9678
  sourceId,
8645
9679
  defaultColumns
8646
9680
  }) {
8647
- return /* @__PURE__ */ jsx41(CopyButtons, { size, ...tableRowCopyProps(copy, row, sourceId, defaultColumns) });
9681
+ return /* @__PURE__ */ jsx42(CopyButtons, { size, ...tableRowCopyProps(copy, row, sourceId, defaultColumns) });
8648
9682
  }
8649
9683
  function tableRowCopyProps(copy, row, sourceId, defaultColumns) {
8650
9684
  const aiVariants = copy.rowAiVariants?.(row);
@@ -8668,8 +9702,8 @@ function isStringArray(value) {
8668
9702
  }
8669
9703
  var activeUrlTableIds = /* @__PURE__ */ new Set();
8670
9704
  function MatrxDataTable(props) {
8671
- if (!props.urlState) return /* @__PURE__ */ jsx41(MatrxDataTableCore, { ...props });
8672
- return /* @__PURE__ */ jsx41(MatrxDataTableWithUrlState, { ...props, urlState: props.urlState });
9705
+ if (!props.urlState) return /* @__PURE__ */ jsx42(MatrxDataTableCore, { ...props });
9706
+ return /* @__PURE__ */ jsx42(MatrxDataTableWithUrlState, { ...props, urlState: props.urlState });
8673
9707
  }
8674
9708
  function MatrxDataTableWithUrlState({
8675
9709
  urlState,
@@ -8724,7 +9758,7 @@ function MatrxDataTableWithUrlState({
8724
9758
  props.selection?.onSelectedIdsChange(ids);
8725
9759
  }
8726
9760
  } : props.selection;
8727
- return /* @__PURE__ */ jsx41(
9761
+ return /* @__PURE__ */ jsx42(
8728
9762
  MatrxDataTableCore,
8729
9763
  {
8730
9764
  ...props,
@@ -8776,7 +9810,7 @@ function opensRowHref(event) {
8776
9810
  return event.metaKey || event.ctrlKey || event.shiftKey || event.button === 1;
8777
9811
  }
8778
9812
  function TableContextPassthrough({ children }) {
8779
- return /* @__PURE__ */ jsx41(Fragment7, { children });
9813
+ return /* @__PURE__ */ jsx42(Fragment7, { children });
8780
9814
  }
8781
9815
  function MatrxDataTableCore({
8782
9816
  data: suppliedData,
@@ -8817,6 +9851,8 @@ function MatrxDataTableCore({
8817
9851
  rowActions,
8818
9852
  footerRows = [],
8819
9853
  rowClassName,
9854
+ cellClassName,
9855
+ tableStyle,
8820
9856
  highlightedIndex,
8821
9857
  onViewChange,
8822
9858
  rowWrapper,
@@ -8962,7 +9998,7 @@ function MatrxDataTableCore({
8962
9998
  setInternalPage(next);
8963
9999
  };
8964
10000
  const [internalPageSize, setInternalPageSize] = useState21(
8965
- defaultPageSize === 0 ? Math.max(data.length, 1) : defaultPageSize
10001
+ defaultPageSize
8966
10002
  );
8967
10003
  const pageSize = controlledQuery ? controlledQuery.state.pageSize : internalPageSize;
8968
10004
  const setPageSize = (next) => {
@@ -9414,6 +10450,48 @@ function MatrxDataTableCore({
9414
10450
  setFixedTableGeometry(geometry);
9415
10451
  }, [resolvedDensity, measureFixedTableGeometry, usesMeasuredFixedLayout]);
9416
10452
  const fixedLayoutActive = usesMeasuredFixedLayout && fixedTableGeometry !== null;
10453
+ const frozenColumns = useMemo7(() => {
10454
+ if (!visibleColumns.some((column) => column.frozen)) return NO_FROZEN_COLUMNS;
10455
+ const ids = visibleColumns.map(columnId);
10456
+ const byId = new Map(visibleColumns.map((column) => [columnId(column), column]));
10457
+ return resolveFrozenColumns(
10458
+ ids,
10459
+ (id) => byId.get(id)?.frozen === true,
10460
+ (id) => effectiveColumnWidths[id] ?? pixelWidth(byId.get(id)?.width),
10461
+ selection ? fixedTableGeometry?.selectionWidth : null
10462
+ );
10463
+ }, [visibleColumns, effectiveColumnWidths, selection, fixedTableGeometry]);
10464
+ const frozenStyle = (id) => {
10465
+ const left = frozenColumns.offsets[id];
10466
+ if (left === void 0) return void 0;
10467
+ return { "--matrx-frozen-left": `${left}px` };
10468
+ };
10469
+ const frozenEdgeId = (() => {
10470
+ const ids = Object.keys(frozenColumns.offsets);
10471
+ return ids.length === 0 ? null : ids[ids.length - 1];
10472
+ })();
10473
+ const styleFieldOf = tableStyle?.fieldOf ?? ((id) => id);
10474
+ const styleDocumentOf = tableStyle?.documentOf ?? ((row) => row);
10475
+ const noChoiceColor = () => void 0;
10476
+ const rowTintClass = (row, id) => {
10477
+ if (!tableStyle) return void 0;
10478
+ const color = resolveRowColor(
10479
+ tableStyle.style,
10480
+ { id, data: styleDocumentOf(row) },
10481
+ tableStyle.choiceColorFor ?? noChoiceColor
10482
+ );
10483
+ return color ? ROW_TINT_CLASS[color] : void 0;
10484
+ };
10485
+ const cellTintClass = (row, id, colId) => {
10486
+ if (!tableStyle) return void 0;
10487
+ const color = resolveCellColor(
10488
+ tableStyle.style,
10489
+ { id, data: styleDocumentOf(row) },
10490
+ styleFieldOf(colId),
10491
+ tableStyle.choiceColorFor ?? noChoiceColor
10492
+ );
10493
+ return color ? CELL_TINT_CLASS[color] : void 0;
10494
+ };
9417
10495
  const declaredVisibleCopyColumns = useMemo7(
9418
10496
  () => visibleColumns.filter((column) => column.accessorFn !== void 0 || column.accessorKey !== void 0),
9419
10497
  [visibleColumns]
@@ -9621,9 +10699,9 @@ function MatrxDataTableCore({
9621
10699
  const showToolbarCopy = effectiveCopy !== void 0 && effectiveCopy.showToolbar !== false;
9622
10700
  const renderRowActions = (row, controls) => {
9623
10701
  const actions = rowActions?.(row, controls);
9624
- const scopedActions = /* @__PURE__ */ jsx41(MatrxTableRowControlsScope, { value: controls, children: actions });
10702
+ const scopedActions = /* @__PURE__ */ jsx42(MatrxTableRowControlsScope, { value: controls, children: actions });
9625
10703
  if (!effectiveCopy || !showRowCopy) return scopedActions;
9626
- return /* @__PURE__ */ jsx41(
10704
+ return /* @__PURE__ */ jsx42(
9627
10705
  MatrxTableRowAlchemyProvider,
9628
10706
  {
9629
10707
  copy: tableRowCopyProps(effectiveCopy, row, `${tableCopySourceNamespace}:row:${getRowId(row)}`, copy === void 0 ? declaredVisibleCopyColumns : void 0),
@@ -9720,7 +10798,7 @@ function MatrxDataTableCore({
9720
10798
  const renderedEmptyState = remoteQuery === null && data.length > 0 && hasActiveFilters ? {
9721
10799
  title: "No matching rows",
9722
10800
  description: "No rows match the current search or filters.",
9723
- action: /* @__PURE__ */ jsx41(Button, { type: "button", variant: "outline", size: "sm", onClick: clearAllFilters, children: "Clear filters" }),
10801
+ action: /* @__PURE__ */ jsx42(Button, { type: "button", variant: "outline", size: "sm", onClick: clearAllFilters, children: "Clear filters" }),
9724
10802
  icon: void 0
9725
10803
  } : emptyState;
9726
10804
  const commitCell = (rowId, field, next) => {
@@ -10092,7 +11170,7 @@ function MatrxDataTableCore({
10092
11170
  const display = renderCell(applyRowEdits(row, rowEdits), col, index);
10093
11171
  const href = col.href?.(row) ?? void 0;
10094
11172
  if (editEnabled && col.editable && (col.editableIf?.(row) ?? true)) {
10095
- return /* @__PURE__ */ jsx41(
11173
+ return /* @__PURE__ */ jsx42(
10096
11174
  EditableTableCell,
10097
11175
  {
10098
11176
  value: rowEdits && field in rowEdits ? rowEdits[field] : getCellValue(row, col),
@@ -10107,7 +11185,7 @@ function MatrxDataTableCore({
10107
11185
  }
10108
11186
  );
10109
11187
  }
10110
- return href ? /* @__PURE__ */ jsx41(Link, { href, onClick: (event) => event.stopPropagation(), className: "block w-full min-w-0 rounded outline-none focus-visible:ring-2 focus-visible:ring-ring", children: display }) : display;
11188
+ return href ? /* @__PURE__ */ jsx42(Link, { href, onClick: (event) => event.stopPropagation(), className: "block w-full min-w-0 rounded outline-none focus-visible:ring-2 focus-visible:ring-ring", children: display }) : display;
10111
11189
  };
10112
11190
  const currentViewSnapshot = useMemo7(
10113
11191
  () => ({
@@ -10213,7 +11291,7 @@ function MatrxDataTableCore({
10213
11291
  },
10214
11292
  [columns, commitColumnState, commitColumnWidths, controlledQuery, intelligentSearchEnabled, intelligentSearchScopes, toolbar]
10215
11293
  );
10216
- return /* @__PURE__ */ jsx41(TooltipProvider, { children: /* @__PURE__ */ jsx41(ContextMenuBoundary, { label: tableId ?? "Data table", children: /* @__PURE__ */ jsxs31(
11294
+ return /* @__PURE__ */ jsx42(TooltipProvider, { children: /* @__PURE__ */ jsx42(ContextMenuBoundary, { label: tableId ?? "Data table", children: /* @__PURE__ */ jsxs32(
10217
11295
  DndContext,
10218
11296
  {
10219
11297
  id: tableDndContextId,
@@ -10306,7 +11384,7 @@ function MatrxDataTableCore({
10306
11384
  commitColumnState(order, effectiveHiddenColumnIds);
10307
11385
  },
10308
11386
  children: [
10309
- /* @__PURE__ */ jsxs31(
11387
+ /* @__PURE__ */ jsxs32(
10310
11388
  "div",
10311
11389
  {
10312
11390
  ref: rootRef,
@@ -10321,14 +11399,14 @@ function MatrxDataTableCore({
10321
11399
  ),
10322
11400
  children: [
10323
11401
  notice,
10324
- savedViewError ? /* @__PURE__ */ jsx41("p", { role: "alert", className: "shrink-0 text-xs text-destructive", children: savedViewError }) : null,
10325
- toolbarActionError ? /* @__PURE__ */ jsx41("p", { role: "alert", className: "shrink-0 text-xs text-destructive", children: toolbarActionError }) : null,
10326
- !hideToolbar && (viewTabs || toolbar?.title || showSearch || toolbar?.anyOf || toolbar?.layeredFilters || toolbar?.facets && toolbar.facets.length > 0 || toolbar?.leading || toolbar?.actions || toolbar?.refresh || toolbar?.add || tableId && SavedViews || hasActiveFilters || showToolbarCopy || columns.length > 0) && /* @__PURE__ */ jsxs31(
11402
+ savedViewError ? /* @__PURE__ */ jsx42("p", { role: "alert", className: "shrink-0 text-xs text-destructive", children: savedViewError }) : null,
11403
+ toolbarActionError ? /* @__PURE__ */ jsx42("p", { role: "alert", className: "shrink-0 text-xs text-destructive", children: toolbarActionError }) : null,
11404
+ !hideToolbar && (viewTabs || toolbar?.title || showSearch || toolbar?.anyOf || toolbar?.layeredFilters || toolbar?.facets && toolbar.facets.length > 0 || toolbar?.leading || toolbar?.actions || toolbar?.refresh || toolbar?.add || tableId && SavedViews || hasActiveFilters || showToolbarCopy || columns.length > 0) && /* @__PURE__ */ jsxs32(
10327
11405
  TableTitleRow,
10328
11406
  {
10329
- tabs: viewTabs ? /* @__PURE__ */ jsx41(TableViewWorkspace, { snapshot: currentViewSnapshot, onApply: applySavedView, related: relatedTableActions }, tableId ?? "table") : void 0,
11407
+ tabs: viewTabs ? /* @__PURE__ */ jsx42(TableViewWorkspace, { snapshot: currentViewSnapshot, onApply: applySavedView, related: relatedTableActions }, tableId ?? "table") : void 0,
10330
11408
  ...toolbar?.title === void 0 ? {} : { title: toolbar.title },
10331
- context: tableId && SavedViews ? /* @__PURE__ */ jsx41("span", { "data-matrx-table-view-control": true, children: /* @__PURE__ */ jsx41(
11409
+ context: tableId && SavedViews ? /* @__PURE__ */ jsx42("span", { "data-matrx-table-view-control": true, children: /* @__PURE__ */ jsx42(
10332
11410
  SavedViews,
10333
11411
  {
10334
11412
  tableId,
@@ -10337,7 +11415,7 @@ function MatrxDataTableCore({
10337
11415
  onApply: applySavedView
10338
11416
  }
10339
11417
  ) }) : void 0,
10340
- search: showSearch ? intelligentSearchEnabled ? /* @__PURE__ */ jsx41(
11418
+ search: showSearch ? intelligentSearchEnabled ? /* @__PURE__ */ jsx42(
10341
11419
  TableSearch,
10342
11420
  {
10343
11421
  value: searchValue,
@@ -10347,7 +11425,7 @@ function MatrxDataTableCore({
10347
11425
  scopes: intelligentSearchScopes,
10348
11426
  ...toolbar?.searchPlaceholder === void 0 ? {} : { placeholder: toolbar.searchPlaceholder }
10349
11427
  }
10350
- ) : /* @__PURE__ */ jsxs31(
11428
+ ) : /* @__PURE__ */ jsxs32(
10351
11429
  "div",
10352
11430
  {
10353
11431
  "data-matrx-table-search": true,
@@ -10356,9 +11434,9 @@ function MatrxDataTableCore({
10356
11434
  toolbar?.searchMatch ? "sm:max-w-md" : "sm:max-w-xs"
10357
11435
  ),
10358
11436
  children: [
10359
- /* @__PURE__ */ jsxs31("div", { className: "relative min-w-0 flex-1", children: [
10360
- /* @__PURE__ */ jsx41(Search, { className: "absolute left-2 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" }),
10361
- /* @__PURE__ */ jsx41(
11437
+ /* @__PURE__ */ jsxs32("div", { className: "relative min-w-0 flex-1", children: [
11438
+ /* @__PURE__ */ jsx42(Search, { className: "absolute left-2 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" }),
11439
+ /* @__PURE__ */ jsx42(
10362
11440
  Input,
10363
11441
  {
10364
11442
  value: searchValue,
@@ -10371,22 +11449,22 @@ function MatrxDataTableCore({
10371
11449
  style: { fontSize: "16px" }
10372
11450
  }
10373
11451
  ),
10374
- searchValue ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
10375
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
11452
+ searchValue ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
11453
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
10376
11454
  "button",
10377
11455
  {
10378
11456
  type: "button",
10379
11457
  "aria-label": "Clear search",
10380
11458
  className: "absolute right-1.5 top-1/2 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground",
10381
11459
  onClick: () => setSearchValue(""),
10382
- children: /* @__PURE__ */ jsx41(X, { className: "h-5 w-5" })
11460
+ children: /* @__PURE__ */ jsx42(X, { className: "h-5 w-5" })
10383
11461
  }
10384
11462
  ) }),
10385
- /* @__PURE__ */ jsx41(TooltipContent, { children: "Clear search" })
11463
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "Clear search" })
10386
11464
  ] }) : null
10387
11465
  ] }),
10388
- toolbar?.searchMatch ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
10389
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs31(
11466
+ toolbar?.searchMatch ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
11467
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs32(
10390
11468
  Button,
10391
11469
  {
10392
11470
  type: "button",
@@ -10399,18 +11477,18 @@ function MatrxDataTableCore({
10399
11477
  searchMatchMode === "whole_words" ? "contains" : "whole_words"
10400
11478
  ),
10401
11479
  children: [
10402
- /* @__PURE__ */ jsx41(WholeWord, { className: "h-5 w-5" }),
11480
+ /* @__PURE__ */ jsx42(WholeWord, { className: "h-5 w-5" }),
10403
11481
  searchMatchMode === "whole_words" ? "Whole words" : "Contains"
10404
11482
  ]
10405
11483
  }
10406
11484
  ) }),
10407
- /* @__PURE__ */ jsx41(TooltipContent, { children: searchMatchMode === "whole_words" ? "Whole words \u2014 click to match text anywhere" : "Contains text \u2014 click to require whole words" })
11485
+ /* @__PURE__ */ jsx42(TooltipContent, { children: searchMatchMode === "whole_words" ? "Whole words \u2014 click to match text anywhere" : "Contains text \u2014 click to require whole words" })
10408
11486
  ] }) : null
10409
11487
  ]
10410
11488
  }
10411
11489
  ) : null,
10412
11490
  children: [
10413
- toolbar?.layeredFilters ? /* @__PURE__ */ jsx41(
11491
+ toolbar?.layeredFilters ? /* @__PURE__ */ jsx42(
10414
11492
  LayeredFilterBuilder,
10415
11493
  {
10416
11494
  fields: toolbar.layeredFilters.fields,
@@ -10420,9 +11498,9 @@ function MatrxDataTableCore({
10420
11498
  label: toolbar.layeredFilters.label
10421
11499
  }
10422
11500
  ) : null,
10423
- toolbar?.anyOf ? /* @__PURE__ */ jsxs31("div", { className: "relative w-full max-w-xs", children: [
10424
- /* @__PURE__ */ jsx41(Search, { className: "absolute left-2 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" }),
10425
- /* @__PURE__ */ jsx41(
11501
+ toolbar?.anyOf ? /* @__PURE__ */ jsxs32("div", { className: "relative w-full max-w-xs", children: [
11502
+ /* @__PURE__ */ jsx42(Search, { className: "absolute left-2 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" }),
11503
+ /* @__PURE__ */ jsx42(
10426
11504
  Input,
10427
11505
  {
10428
11506
  value: anyOfValue,
@@ -10432,22 +11510,22 @@ function MatrxDataTableCore({
10432
11510
  style: { fontSize: "16px" }
10433
11511
  }
10434
11512
  ),
10435
- anyOfValue ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
10436
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
11513
+ anyOfValue ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
11514
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
10437
11515
  "button",
10438
11516
  {
10439
11517
  type: "button",
10440
11518
  "aria-label": "Clear match-any search",
10441
11519
  className: "absolute right-1.5 top-1/2 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground",
10442
11520
  onClick: () => setAnyOfValue(""),
10443
- children: /* @__PURE__ */ jsx41(X, { className: "h-5 w-5" })
11521
+ children: /* @__PURE__ */ jsx42(X, { className: "h-5 w-5" })
10444
11522
  }
10445
11523
  ) }),
10446
- /* @__PURE__ */ jsx41(TooltipContent, { children: "Clear match-any search" })
11524
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "Clear match-any search" })
10447
11525
  ] }) : null
10448
11526
  ] }) : null,
10449
- renderedFacets ? /* @__PURE__ */ jsx41(ToolbarFacets, { facets: renderedFacets }) : null,
10450
- toolbar?.leading ? /* @__PURE__ */ jsx41(
11527
+ renderedFacets ? /* @__PURE__ */ jsx42(ToolbarFacets, { facets: renderedFacets }) : null,
11528
+ toolbar?.leading ? /* @__PURE__ */ jsx42(
10451
11529
  "div",
10452
11530
  {
10453
11531
  "data-matrx-table-toolbar-extras": true,
@@ -10455,30 +11533,13 @@ function MatrxDataTableCore({
10455
11533
  children: toolbar.leading
10456
11534
  }
10457
11535
  ) : null,
10458
- /* @__PURE__ */ jsxs31(
11536
+ /* @__PURE__ */ jsxs32(
10459
11537
  "div",
10460
11538
  {
10461
11539
  "data-matrx-table-actions": true,
10462
11540
  className: "ml-auto flex min-w-0 flex-wrap items-center gap-0",
10463
11541
  children: [
10464
- sourceTotal !== void 0 ? /* @__PURE__ */ jsxs31(
10465
- "span",
10466
- {
10467
- "data-matrx-table-source-total": true,
10468
- className: "text-xs tabular-nums text-muted-foreground",
10469
- children: [
10470
- data.length.toLocaleString(),
10471
- " loaded of",
10472
- " ",
10473
- Math.max(0, sourceTotal).toLocaleString(),
10474
- " \xB7",
10475
- " ",
10476
- processed.length.toLocaleString(),
10477
- " matched"
10478
- ]
10479
- }
10480
- ) : null,
10481
- /* @__PURE__ */ jsx41(
11542
+ /* @__PURE__ */ jsx42(
10482
11543
  TableToolbarAction,
10483
11544
  {
10484
11545
  HostAction: host.ToolbarAction,
@@ -10486,10 +11547,10 @@ function MatrxDataTableCore({
10486
11547
  tooltip: hasActiveFilters ? "Clear search and filters; keep columns and sort" : "No search or filters to clear",
10487
11548
  disabled: !hasActiveFilters,
10488
11549
  onClick: clearAllFilters,
10489
- children: /* @__PURE__ */ jsx41(Eraser, {})
11550
+ children: /* @__PURE__ */ jsx42(Eraser, {})
10490
11551
  }
10491
11552
  ),
10492
- showToolbarCopy && effectiveCopy ? /* @__PURE__ */ jsx41(
11553
+ showToolbarCopy && effectiveCopy ? /* @__PURE__ */ jsx42(
10493
11554
  CopyButtons,
10494
11555
  {
10495
11556
  size: "toolbar",
@@ -10532,17 +11593,17 @@ function MatrxDataTableCore({
10532
11593
  }
10533
11594
  }
10534
11595
  ) : null,
10535
- columns.length > 0 ? /* @__PURE__ */ jsx41(
11596
+ columns.length > 0 ? /* @__PURE__ */ jsx42(
10536
11597
  TableToolbarAction,
10537
11598
  {
10538
11599
  HostAction: host.ToolbarAction,
10539
11600
  ariaLabel: "Columns",
10540
11601
  tooltip: "Show, hide, or reorder columns",
10541
11602
  onClick: () => setColumnManagerOpen(true),
10542
- children: /* @__PURE__ */ jsx41(SlidersHorizontal, {})
11603
+ children: /* @__PURE__ */ jsx42(SlidersHorizontal, {})
10543
11604
  }
10544
11605
  ) : null,
10545
- toolbar?.refresh ? /* @__PURE__ */ jsx41(
11606
+ toolbar?.refresh ? /* @__PURE__ */ jsx42(
10546
11607
  TableToolbarAction,
10547
11608
  {
10548
11609
  HostAction: host.ToolbarAction,
@@ -10564,10 +11625,10 @@ function MatrxDataTableCore({
10564
11625
  setToolbarActionPending((current) => ({ ...current, refresh: false }));
10565
11626
  });
10566
11627
  },
10567
- children: /* @__PURE__ */ jsx41(RefreshControlIcon, { spinning: isFetching || toolbarActionPending.refresh })
11628
+ children: /* @__PURE__ */ jsx42(RefreshControlIcon, { spinning: isFetching || toolbarActionPending.refresh })
10568
11629
  }
10569
11630
  ) : null,
10570
- toolbar?.add ? /* @__PURE__ */ jsx41(
11631
+ toolbar?.add ? /* @__PURE__ */ jsx42(
10571
11632
  TableToolbarAction,
10572
11633
  {
10573
11634
  HostAction: host.ToolbarAction,
@@ -10589,7 +11650,7 @@ function MatrxDataTableCore({
10589
11650
  setToolbarActionPending((current) => ({ ...current, add: false }));
10590
11651
  });
10591
11652
  },
10592
- children: /* @__PURE__ */ jsx41(Plus, {})
11653
+ children: /* @__PURE__ */ jsx42(Plus, {})
10593
11654
  }
10594
11655
  ) : null,
10595
11656
  toolbar?.actions
@@ -10599,15 +11660,15 @@ function MatrxDataTableCore({
10599
11660
  ]
10600
11661
  }
10601
11662
  ),
10602
- selection && selectionCount > 0 ? /* @__PURE__ */ jsxs31("div", { className: "flex shrink-0 flex-wrap items-center gap-2 rounded-md border border-primary/30 bg-primary/5 px-2 py-1.5", children: [
10603
- /* @__PURE__ */ jsxs31("span", { className: "text-xs font-medium text-foreground", children: [
11663
+ selection && selectionCount > 0 ? /* @__PURE__ */ jsxs32("div", { className: "flex shrink-0 flex-wrap items-center gap-2 rounded-md border border-primary/30 bg-primary/5 px-2 py-1.5", children: [
11664
+ /* @__PURE__ */ jsxs32("span", { className: "text-xs font-medium text-foreground", children: [
10604
11665
  formatCount3(selectionCount),
10605
11666
  " ",
10606
11667
  selectionNoun,
10607
11668
  selectionCount === 1 ? "" : "s",
10608
11669
  " selected"
10609
11670
  ] }),
10610
- /* @__PURE__ */ jsxs31(
11671
+ /* @__PURE__ */ jsxs32(
10611
11672
  Button,
10612
11673
  {
10613
11674
  type: "button",
@@ -10619,13 +11680,13 @@ function MatrxDataTableCore({
10619
11680
  selection.onSelectedIdsChange([]);
10620
11681
  },
10621
11682
  children: [
10622
- /* @__PURE__ */ jsx41(X, { className: "h-3.5 w-3.5" }),
11683
+ /* @__PURE__ */ jsx42(X, { className: "h-3.5 w-3.5" }),
10623
11684
  "Clear"
10624
11685
  ]
10625
11686
  }
10626
11687
  ),
10627
- /* @__PURE__ */ jsxs31("div", { className: "ml-auto flex flex-wrap items-center gap-1.5", children: [
10628
- effectiveCopy && selectedRows.length > 0 ? /* @__PURE__ */ jsx41(
11688
+ /* @__PURE__ */ jsxs32("div", { className: "ml-auto flex flex-wrap items-center gap-1.5", children: [
11689
+ effectiveCopy && selectedRows.length > 0 ? /* @__PURE__ */ jsx42(
10629
11690
  CopyButtons,
10630
11691
  {
10631
11692
  size: "icon",
@@ -10658,9 +11719,9 @@ function MatrxDataTableCore({
10658
11719
  selection.actions?.(selectedRows, selection.selectedIds)
10659
11720
  ] })
10660
11721
  ] }) : null,
10661
- /* @__PURE__ */ jsxs31("div", { "data-matrx-table-body-region": true, className: "flex min-h-0 flex-1 flex-col gap-2", children: [
10662
- /* @__PURE__ */ jsxs31("div", { className: "relative min-h-0 flex-1", children: [
10663
- mobileCards ? /* @__PURE__ */ jsxs31(
11722
+ /* @__PURE__ */ jsxs32("div", { "data-matrx-table-body-region": true, className: "flex min-h-0 flex-1 flex-col gap-2", children: [
11723
+ /* @__PURE__ */ jsxs32("div", { className: "relative min-h-0 flex-1", children: [
11724
+ mobileCards ? /* @__PURE__ */ jsxs32(
10664
11725
  "div",
10665
11726
  {
10666
11727
  ref: cardsScrollRef,
@@ -10672,34 +11733,34 @@ function MatrxDataTableCore({
10672
11733
  mobileCardsClass
10673
11734
  ),
10674
11735
  children: [
10675
- isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ jsxs31(
11736
+ isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ jsxs32(
10676
11737
  "div",
10677
11738
  {
10678
11739
  role: "status",
10679
11740
  className: "pointer-events-none absolute inset-x-0 top-0 z-20 h-0.5 overflow-hidden bg-primary/15",
10680
11741
  children: [
10681
- /* @__PURE__ */ jsx41("div", { className: "h-full w-full animate-pulse bg-primary" }),
10682
- /* @__PURE__ */ jsx41("span", { className: "sr-only", children: "Refreshing table data" })
11742
+ /* @__PURE__ */ jsx42("div", { className: "h-full w-full animate-pulse bg-primary" }),
11743
+ /* @__PURE__ */ jsx42("span", { className: "sr-only", children: "Refreshing table data" })
10683
11744
  ]
10684
11745
  }
10685
11746
  ) : null,
10686
- isLoading ? Array.from({ length: 4 }).map((_, index) => /* @__PURE__ */ jsx41(
11747
+ isLoading ? Array.from({ length: 4 }).map((_, index) => /* @__PURE__ */ jsx42(
10687
11748
  Skeleton,
10688
11749
  {
10689
11750
  className: "h-52 w-full shrink-0 rounded-lg"
10690
11751
  },
10691
11752
  `mobile-card-sk-${index}`
10692
- )) : paginated.length === 0 ? /* @__PURE__ */ jsx41("div", { className: "flex min-h-48 flex-1 items-center justify-center px-4 py-12 text-center", children: /* @__PURE__ */ jsxs31("div", { className: "flex max-w-sm flex-col items-center gap-2", children: [
11753
+ )) : paginated.length === 0 ? /* @__PURE__ */ jsx42("div", { className: "flex min-h-48 flex-1 items-center justify-center px-4 py-12 text-center", children: /* @__PURE__ */ jsxs32("div", { className: "flex max-w-sm flex-col items-center gap-2", children: [
10693
11754
  renderedEmptyState?.icon,
10694
- /* @__PURE__ */ jsx41("p", { className: "text-sm font-medium text-foreground", children: renderedEmptyState?.title ?? "No rows" }),
10695
- renderedEmptyState?.description ? /* @__PURE__ */ jsx41("p", { className: "text-xs text-muted-foreground", children: renderedEmptyState.description }) : null,
11755
+ /* @__PURE__ */ jsx42("p", { className: "text-sm font-medium text-foreground", children: renderedEmptyState?.title ?? "No rows" }),
11756
+ renderedEmptyState?.description ? /* @__PURE__ */ jsx42("p", { className: "text-xs text-muted-foreground", children: renderedEmptyState.description }) : null,
10696
11757
  renderedEmptyState?.action
10697
11758
  ] }) }) : paginated.map((row, index) => {
10698
11759
  const id = getRowId(row);
10699
11760
  const displayRow = applyRowEdits(row, edits[id]);
10700
11761
  const controls = buildRecordControls(displayRow);
10701
11762
  const selectable = selection?.isRowSelectable?.(row) ?? Boolean(selection);
10702
- return /* @__PURE__ */ jsx41("div", { "data-row-id": id, className: "contents", children: mobileCards(displayRow, index, {
11763
+ return /* @__PURE__ */ jsx42("div", { "data-row-id": id, className: "contents", children: mobileCards(displayRow, index, {
10703
11764
  renderCell: (columnKey) => {
10704
11765
  const column = columns.find((candidate) => columnId(candidate) === columnKey);
10705
11766
  return column ? renderRecordCell(row, column, index) : null;
@@ -10715,14 +11776,14 @@ function MatrxDataTableCore({
10715
11776
  else next.delete(id);
10716
11777
  setSelectedIds(next);
10717
11778
  },
10718
- actions: showInlineRowCopy || rowActions ? /* @__PURE__ */ jsxs31(
11779
+ actions: showInlineRowCopy || rowActions ? /* @__PURE__ */ jsxs32(
10719
11780
  "div",
10720
11781
  {
10721
11782
  "data-matrx-table-row-actions": true,
10722
11783
  className: "inline-flex items-center justify-end gap-0",
10723
11784
  onClick: (event) => event.stopPropagation(),
10724
11785
  children: [
10725
- showInlineRowCopy && effectiveCopy ? /* @__PURE__ */ jsx41(
11786
+ showInlineRowCopy && effectiveCopy ? /* @__PURE__ */ jsx42(
10726
11787
  TableRowCopyControl,
10727
11788
  {
10728
11789
  size: "toolbar",
@@ -10743,7 +11804,7 @@ function MatrxDataTableCore({
10743
11804
  expandedDetail: expandedDetail && isRowExpanded(row) ? expandedDetail.render(displayRow, controls) : null
10744
11805
  }) }, id);
10745
11806
  }),
10746
- appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ jsxs31(
11807
+ appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ jsxs32(
10747
11808
  "div",
10748
11809
  {
10749
11810
  "data-matrx-table-append-loading-card": true,
@@ -10751,7 +11812,7 @@ function MatrxDataTableCore({
10751
11812
  "aria-live": "polite",
10752
11813
  className: "sticky bottom-0 z-20 flex h-16 w-full max-w-[100cqw] shrink-0 items-center justify-center gap-2 rounded-md border border-border bg-card/95 px-3 text-sm font-medium text-foreground shadow-sm backdrop-blur-sm",
10753
11814
  children: [
10754
- /* @__PURE__ */ jsx41(
11815
+ /* @__PURE__ */ jsx42(
10755
11816
  Loader2,
10756
11817
  {
10757
11818
  "aria-hidden": "true",
@@ -10765,7 +11826,7 @@ function MatrxDataTableCore({
10765
11826
  ]
10766
11827
  }
10767
11828
  ) : null,
10768
- /* @__PURE__ */ jsxs31(
11829
+ /* @__PURE__ */ jsxs32(
10769
11830
  "div",
10770
11831
  {
10771
11832
  ref: scrollRef,
@@ -10779,32 +11840,32 @@ function MatrxDataTableCore({
10779
11840
  tableClassName
10780
11841
  ),
10781
11842
  children: [
10782
- hierarchy && draggedRow ? /* @__PURE__ */ jsx41(
11843
+ hierarchy && draggedRow ? /* @__PURE__ */ jsx42(
10783
11844
  HierarchyRootDropTarget,
10784
11845
  {
10785
11846
  label: hierarchy.rootDropLabel ?? "Drop here to move to the top level",
10786
11847
  draggedLabel: hierarchy.itemLabel?.(draggedRow) ?? "Moving row"
10787
11848
  }
10788
11849
  ) : null,
10789
- hierarchy && draggedRowId ? /* @__PURE__ */ jsx41(
11850
+ hierarchy && draggedRowId ? /* @__PURE__ */ jsx42(
10790
11851
  HierarchyDragIndicatorLayer,
10791
11852
  {
10792
11853
  scrollRef,
10793
11854
  resolve: resolveHierarchyMove
10794
11855
  }
10795
11856
  ) : null,
10796
- isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ jsxs31(
11857
+ isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ jsxs32(
10797
11858
  "div",
10798
11859
  {
10799
11860
  role: "status",
10800
11861
  className: "pointer-events-none absolute inset-x-0 top-0 z-20 h-0.5 overflow-hidden bg-primary/15",
10801
11862
  children: [
10802
- /* @__PURE__ */ jsx41("div", { className: "h-full w-full animate-pulse bg-primary" }),
10803
- /* @__PURE__ */ jsx41("span", { className: "sr-only", children: "Refreshing table data" })
11863
+ /* @__PURE__ */ jsx42("div", { className: "h-full w-full animate-pulse bg-primary" }),
11864
+ /* @__PURE__ */ jsx42("span", { className: "sr-only", children: "Refreshing table data" })
10804
11865
  ]
10805
11866
  }
10806
11867
  ) : null,
10807
- /* @__PURE__ */ jsxs31(
11868
+ /* @__PURE__ */ jsxs32(
10808
11869
  "table",
10809
11870
  {
10810
11871
  ref: tableRef,
@@ -10822,7 +11883,7 @@ function MatrxDataTableCore({
10822
11883
  fixedLayoutActive && "sm:table-fixed sm:max-w-none sm:w-[var(--matrx-resized-table-width)]"
10823
11884
  ),
10824
11885
  children: [
10825
- /* @__PURE__ */ jsx41(
11886
+ /* @__PURE__ */ jsx42(
10826
11887
  "thead",
10827
11888
  {
10828
11889
  ref: tableHeaderRef,
@@ -10831,14 +11892,14 @@ function MatrxDataTableCore({
10831
11892
  "z-10 border-b border-border bg-muted/90 shadow-[0_1px_0_0_var(--border)] backdrop-blur-sm",
10832
11893
  stickyHeader && (documentStickyHeader ? "relative translate-y-[var(--matrx-document-sticky-offset)]" : "sticky top-0")
10833
11894
  ),
10834
- children: /* @__PURE__ */ jsxs31("tr", { children: [
10835
- selection ? /* @__PURE__ */ jsx41(
11895
+ children: /* @__PURE__ */ jsxs32("tr", { children: [
11896
+ selection ? /* @__PURE__ */ jsx42(
10836
11897
  "th",
10837
11898
  {
10838
11899
  "data-matrx-table-selection-column": true,
10839
11900
  className: "h-9 w-9 px-2 text-left align-middle",
10840
11901
  style: fixedUtilityWidth(fixedTableGeometry?.selectionWidth),
10841
- children: /* @__PURE__ */ jsx41(
11902
+ children: /* @__PURE__ */ jsx42(
10842
11903
  "div",
10843
11904
  {
10844
11905
  "data-matrx-table-selection-target": true,
@@ -10847,7 +11908,7 @@ function MatrxDataTableCore({
10847
11908
  event.currentTarget.querySelector('[role="checkbox"]')?.click();
10848
11909
  }
10849
11910
  },
10850
- children: /* @__PURE__ */ jsx41(
11911
+ children: /* @__PURE__ */ jsx42(
10851
11912
  Checkbox,
10852
11913
  {
10853
11914
  className: CHECKBOX_TAP_AREA,
@@ -10873,7 +11934,7 @@ function MatrxDataTableCore({
10873
11934
  const compact = col.compact || marker !== void 0;
10874
11935
  const width = marker && col.width === void 0 ? 40 : col.width;
10875
11936
  const minWidth = marker && col.minWidth === void 0 ? 40 : col.minWidth;
10876
- return /* @__PURE__ */ jsxs31(
11937
+ return /* @__PURE__ */ jsxs32(
10877
11938
  "th",
10878
11939
  {
10879
11940
  "data-matrx-table-column-id": id,
@@ -10898,12 +11959,17 @@ function MatrxDataTableCore({
10898
11959
  (width !== void 0 || columnResizable) && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)]",
10899
11960
  col.headerClassName,
10900
11961
  isColumnDragShadow && "bg-primary/10 shadow-[inset_2px_0_0_var(--primary),inset_-2px_0_0_var(--primary)]",
10901
- col.align === "center" && "text-center",
10902
- col.align === "right" && "text-right"
11962
+ alignForFormat(col) === "center" && "text-center",
11963
+ alignForFormat(col) === "right" && "text-right",
11964
+ frozenColumns.offsets[id] !== void 0 && FROZEN_HEADER_CLASS,
11965
+ frozenEdgeId === id && FROZEN_EDGE_CLASS
10903
11966
  ),
10904
- style: columnWidthVar(width, effectiveColumnWidths[id], id, columnResizable),
11967
+ style: {
11968
+ ...columnWidthVar(width, effectiveColumnWidths[id], id, columnResizable),
11969
+ ...frozenStyle(id)
11970
+ },
10905
11971
  children: [
10906
- /* @__PURE__ */ jsx41(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: /* @__PURE__ */ jsx41(
11972
+ /* @__PURE__ */ jsx42(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: /* @__PURE__ */ jsx42(
10907
11973
  ColumnHeaderCell,
10908
11974
  {
10909
11975
  label: col.header,
@@ -10942,7 +12008,7 @@ function MatrxDataTableCore({
10942
12008
  reorderColumn: reorderableColumns ? { id, label: headerLabel } : void 0
10943
12009
  }
10944
12010
  ) }),
10945
- columnResizable ? /* @__PURE__ */ jsx41(
12011
+ columnResizable ? /* @__PURE__ */ jsx42(
10946
12012
  ColumnResizeHandle,
10947
12013
  {
10948
12014
  columnId: id,
@@ -10963,22 +12029,22 @@ function MatrxDataTableCore({
10963
12029
  id
10964
12030
  );
10965
12031
  }),
10966
- showActionsCol && /* @__PURE__ */ jsx41(
12032
+ showActionsCol && /* @__PURE__ */ jsx42(
10967
12033
  "th",
10968
12034
  {
10969
12035
  "data-matrx-table-actions-column": true,
10970
12036
  className: "h-9 w-px whitespace-nowrap px-2 text-right align-middle text-xs font-semibold uppercase tracking-wide text-muted-foreground",
10971
12037
  style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth),
10972
- children: /* @__PURE__ */ jsx41("span", { "data-matrx-table-actions-label": true, className: "inline-block whitespace-nowrap", children: "Actions" })
12038
+ children: /* @__PURE__ */ jsx42("span", { "data-matrx-table-actions-label": true, className: "inline-block whitespace-nowrap", children: "Actions" })
10973
12039
  }
10974
12040
  )
10975
12041
  ] })
10976
12042
  }
10977
12043
  ),
10978
- /* @__PURE__ */ jsxs31("tbody", { children: [
10979
- isLoading ? Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs31("tr", { className: "border-b border-border/60", children: [
10980
- selection ? /* @__PURE__ */ jsx41("td", { className: "px-2 py-2", style: fixedUtilityWidth(fixedTableGeometry?.selectionWidth), children: /* @__PURE__ */ jsx41(Skeleton, { className: "h-3.5 w-3.5" }) }) : null,
10981
- visibleColumns.map((col) => /* @__PURE__ */ jsx41(
12044
+ /* @__PURE__ */ jsxs32("tbody", { children: [
12045
+ isLoading ? Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs32("tr", { className: "border-b border-border/60", children: [
12046
+ selection ? /* @__PURE__ */ jsx42("td", { className: "px-2 py-2", style: fixedUtilityWidth(fixedTableGeometry?.selectionWidth), children: /* @__PURE__ */ jsx42(Skeleton, { className: "h-3.5 w-3.5" }) }) : null,
12047
+ visibleColumns.map((col) => /* @__PURE__ */ jsx42(
10982
12048
  "td",
10983
12049
  {
10984
12050
  className: cn(
@@ -10986,20 +12052,20 @@ function MatrxDataTableCore({
10986
12052
  col.compact || resolveColumnMarker(col) !== void 0 ? "px-1" : "px-2",
10987
12053
  col.mobileHidden && "max-sm:hidden"
10988
12054
  ),
10989
- children: /* @__PURE__ */ jsx41(Skeleton, { className: "h-5 w-full" })
12055
+ children: /* @__PURE__ */ jsx42(Skeleton, { className: "h-5 w-full" })
10990
12056
  },
10991
12057
  columnId(col)
10992
12058
  )),
10993
- showActionsCol && /* @__PURE__ */ jsx41("td", { className: "text-right align-middle", style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth), children: /* @__PURE__ */ jsx41(Skeleton, { className: "ml-auto h-5 w-10" }) })
10994
- ] }, `sk-${i}`)) : paginated.length === 0 ? /* @__PURE__ */ jsx41("tr", { children: /* @__PURE__ */ jsx41(
12059
+ showActionsCol && /* @__PURE__ */ jsx42("td", { className: "text-right align-middle", style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth), children: /* @__PURE__ */ jsx42(Skeleton, { className: "ml-auto h-5 w-10" }) })
12060
+ ] }, `sk-${i}`)) : paginated.length === 0 ? /* @__PURE__ */ jsx42("tr", { children: /* @__PURE__ */ jsx42(
10995
12061
  "td",
10996
12062
  {
10997
12063
  colSpan: visibleColumns.length + leadingCols + (showActionsCol ? 1 : 0),
10998
12064
  className: "px-0 py-12 text-center",
10999
- children: /* @__PURE__ */ jsxs31("div", { "data-matrx-table-empty-state": true, className: "sticky left-0 flex flex-col items-center gap-2 whitespace-normal px-4", style: { width: "100cqw", maxWidth: "100%" }, children: [
12065
+ children: /* @__PURE__ */ jsxs32("div", { "data-matrx-table-empty-state": true, className: "sticky left-0 flex flex-col items-center gap-2 whitespace-normal px-4", style: { width: "100cqw", maxWidth: "100%" }, children: [
11000
12066
  renderedEmptyState?.icon,
11001
- /* @__PURE__ */ jsx41("p", { className: "text-sm font-medium text-foreground", children: renderedEmptyState?.title ?? "No rows" }),
11002
- renderedEmptyState?.description ? /* @__PURE__ */ jsx41("p", { className: "text-xs text-muted-foreground", children: renderedEmptyState.description }) : null,
12067
+ /* @__PURE__ */ jsx42("p", { className: "text-sm font-medium text-foreground", children: renderedEmptyState?.title ?? "No rows" }),
12068
+ renderedEmptyState?.description ? /* @__PURE__ */ jsx42("p", { className: "text-xs text-muted-foreground", children: renderedEmptyState.description }) : null,
11003
12069
  renderedEmptyState?.action
11004
12070
  ] })
11005
12071
  }
@@ -11010,7 +12076,7 @@ function MatrxDataTableCore({
11010
12076
  const displayRow = applyRowEdits(row, rowEdits);
11011
12077
  const controls = buildRecordControls(displayRow);
11012
12078
  const isChecked = selectedIdSet.has(id);
11013
- const rowNode = /* @__PURE__ */ jsxs31(
12079
+ const rowNode = /* @__PURE__ */ jsxs32(
11014
12080
  "tr",
11015
12081
  {
11016
12082
  "data-row-id": id,
@@ -11043,16 +12109,28 @@ function MatrxDataTableCore({
11043
12109
  highlightedIndex === index && "bg-muted ring-1 ring-inset ring-primary/60",
11044
12110
  rowClassName?.(row, index),
11045
12111
  draggedRowId === id && "opacity-40",
11046
- zebra && index % 2 === 1 && !isSelected && !isChecked && "sm:bg-muted/20"
12112
+ zebra && index % 2 === 1 && !isSelected && !isChecked && "sm:bg-muted/20",
12113
+ // LAST so a colored row STAYS colored while selected
12114
+ // and on an odd zebra stripe — `cn` is tailwind-merge
12115
+ // and keeps the last background of a group. The
12116
+ // checkbox already says the row is selected; the tint
12117
+ // is the only thing saying WHY the row matters.
12118
+ rowTintClass(row, id)
11047
12119
  ),
11048
12120
  children: [
11049
- selection ? /* @__PURE__ */ jsx41(
12121
+ selection ? /* @__PURE__ */ jsx42(
11050
12122
  "td",
11051
12123
  {
11052
- className: "px-2 py-1.5 align-middle lg:py-0.5",
12124
+ className: cn(
12125
+ "px-2 py-1.5 align-middle lg:py-0.5",
12126
+ // When a data column is frozen the checkbox
12127
+ // column has to freeze with it, or the first
12128
+ // frozen column slides over the checkboxes.
12129
+ frozenColumns.selectionOffset !== null && "sm:sticky sm:left-0 sm:z-20 sm:bg-inherit"
12130
+ ),
11053
12131
  style: fixedUtilityWidth(fixedTableGeometry?.selectionWidth),
11054
12132
  onClick: (e) => e.stopPropagation(),
11055
- children: selection.isRowSelectable?.(row) ?? true ? /* @__PURE__ */ jsx41(
12133
+ children: selection.isRowSelectable?.(row) ?? true ? /* @__PURE__ */ jsx42(
11056
12134
  "div",
11057
12135
  {
11058
12136
  "data-matrx-table-selection-target": true,
@@ -11061,7 +12139,7 @@ function MatrxDataTableCore({
11061
12139
  event.currentTarget.querySelector('[role="checkbox"]')?.click();
11062
12140
  }
11063
12141
  },
11064
- children: /* @__PURE__ */ jsx41(
12142
+ children: /* @__PURE__ */ jsx42(
11065
12143
  Checkbox,
11066
12144
  {
11067
12145
  className: CHECKBOX_TAP_AREA,
@@ -11076,7 +12154,7 @@ function MatrxDataTableCore({
11076
12154
  ) : null,
11077
12155
  visibleColumns.map((col, colIdx) => {
11078
12156
  const isColumnDragShadow = columnDragPreview?.draggedId === columnId(col) && columnDragPreview.targetId !== null;
11079
- return /* @__PURE__ */ jsx41(
12157
+ return /* @__PURE__ */ jsx42(
11080
12158
  "td",
11081
12159
  {
11082
12160
  "data-matrx-table-column-id": columnId(col),
@@ -11091,23 +12169,33 @@ function MatrxDataTableCore({
11091
12169
  ((resolveColumnMarker(col) && col.width === void 0 ? 40 : col.width) !== void 0 || resizableColumns && col.resizable !== false) && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)] sm:max-w-[var(--matrx-col-w)]",
11092
12170
  col.className,
11093
12171
  isColumnDragShadow && "bg-primary/10 shadow-[inset_2px_0_0_var(--primary),inset_-2px_0_0_var(--primary)]",
11094
- col.align === "center" && "text-center",
11095
- col.align === "right" && "text-right"
12172
+ alignForFormat(col) === "center" && "text-center",
12173
+ alignForFormat(col) === "right" && "text-right",
12174
+ frozenColumns.offsets[columnId(col)] !== void 0 && FROZEN_CELL_CLASS,
12175
+ frozenEdgeId === columnId(col) && FROZEN_EDGE_CLASS,
12176
+ // A cell tint paints OVER the row tint beneath
12177
+ // it, and the consumer's own hook comes last so
12178
+ // it can always win.
12179
+ cellTintClass(row, id, columnId(col)),
12180
+ cellClassName?.(row, columnId(col), index)
11096
12181
  ),
11097
- style: columnWidthVar(
11098
- resolveColumnMarker(col) && col.width === void 0 ? 40 : col.width,
11099
- effectiveColumnWidths[columnId(col)],
11100
- columnId(col),
11101
- resizableColumns && col.resizable !== false
11102
- ),
11103
- children: /* @__PURE__ */ jsxs31(
12182
+ style: {
12183
+ ...columnWidthVar(
12184
+ resolveColumnMarker(col) && col.width === void 0 ? 40 : col.width,
12185
+ effectiveColumnWidths[columnId(col)],
12186
+ columnId(col),
12187
+ resizableColumns && col.resizable !== false
12188
+ ),
12189
+ ...frozenStyle(columnId(col))
12190
+ },
12191
+ children: /* @__PURE__ */ jsxs32(
11104
12192
  "div",
11105
12193
  {
11106
12194
  className: cn(
11107
12195
  colIdx === 0 && hierarchy && "flex min-w-0 items-center"
11108
12196
  ),
11109
12197
  children: [
11110
- colIdx === 0 && hierarchy ? /* @__PURE__ */ jsx41(
12198
+ colIdx === 0 && hierarchy ? /* @__PURE__ */ jsx42(
11111
12199
  HierarchyDragHandle,
11112
12200
  {
11113
12201
  id,
@@ -11115,7 +12203,7 @@ function MatrxDataTableCore({
11115
12203
  disabled: !(hierarchy.canReparent?.(row) ?? true)
11116
12204
  }
11117
12205
  ) : null,
11118
- /* @__PURE__ */ jsx41(
12206
+ /* @__PURE__ */ jsx42(
11119
12207
  "div",
11120
12208
  {
11121
12209
  "data-matrx-cell-content": true,
@@ -11130,20 +12218,20 @@ function MatrxDataTableCore({
11130
12218
  columnId(col)
11131
12219
  );
11132
12220
  }),
11133
- showActionsCol && /* @__PURE__ */ jsx41(
12221
+ showActionsCol && /* @__PURE__ */ jsx42(
11134
12222
  "td",
11135
12223
  {
11136
12224
  "data-matrx-table-row-action-cell": true,
11137
12225
  className: "text-right align-middle",
11138
12226
  style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth),
11139
- children: /* @__PURE__ */ jsxs31(
12227
+ children: /* @__PURE__ */ jsxs32(
11140
12228
  "div",
11141
12229
  {
11142
12230
  "data-matrx-table-row-actions": true,
11143
12231
  className: "inline-flex items-center justify-end gap-0",
11144
12232
  onClick: (e) => e.stopPropagation(),
11145
12233
  children: [
11146
- showInlineRowCopy && effectiveCopy ? /* @__PURE__ */ jsx41(
12234
+ showInlineRowCopy && effectiveCopy ? /* @__PURE__ */ jsx42(
11147
12235
  TableRowCopyControl,
11148
12236
  {
11149
12237
  size: "toolbar",
@@ -11154,8 +12242,8 @@ function MatrxDataTableCore({
11154
12242
  }
11155
12243
  ) : null,
11156
12244
  renderRowActions(displayRow, controls),
11157
- windowEnabled ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11158
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12245
+ windowEnabled ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12246
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11159
12247
  Button,
11160
12248
  {
11161
12249
  type: "button",
@@ -11169,10 +12257,10 @@ function MatrxDataTableCore({
11169
12257
  if (windowConfig?.openOnRowClick === true) openDetail(row);
11170
12258
  else openWindow(row);
11171
12259
  },
11172
- children: opensWindowOnRowClick ? /* @__PURE__ */ jsx41(PanelRightOpen, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx41(PanelRight, { className: "h-5 w-5" })
12260
+ children: opensWindowOnRowClick ? /* @__PURE__ */ jsx42(PanelRightOpen, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx42(PanelRight, { className: "h-5 w-5" })
11173
12261
  }
11174
12262
  ) }),
11175
- /* @__PURE__ */ jsx41(TooltipContent, { children: windowConfig?.openOnRowClick === true ? "Open in side panel" : "Open in window" })
12263
+ /* @__PURE__ */ jsx42(TooltipContent, { children: windowConfig?.openOnRowClick === true ? "Open in side panel" : "Open in window" })
11176
12264
  ] }) : null
11177
12265
  ]
11178
12266
  }
@@ -11184,12 +12272,12 @@ function MatrxDataTableCore({
11184
12272
  id
11185
12273
  );
11186
12274
  const wrappedRow = rowWrapper ? rowWrapper(row, rowNode) : rowNode;
11187
- const inlineDetail = expandedDetail && isRowExpanded(row) ? /* @__PURE__ */ jsx41(
12275
+ const inlineDetail = expandedDetail && isRowExpanded(row) ? /* @__PURE__ */ jsx42(
11188
12276
  "tr",
11189
12277
  {
11190
12278
  "data-matrx-table-expanded-detail": id,
11191
12279
  className: cn("bg-muted/20", expandedDetail.className),
11192
- children: /* @__PURE__ */ jsx41(
12280
+ children: /* @__PURE__ */ jsx42(
11193
12281
  "td",
11194
12282
  {
11195
12283
  colSpan: visibleColumns.length + leadingCols + (showActionsCol ? 1 : 0),
@@ -11200,8 +12288,8 @@ function MatrxDataTableCore({
11200
12288
  },
11201
12289
  `${id}:expanded-detail`
11202
12290
  ) : null;
11203
- return hierarchy ? /* @__PURE__ */ jsxs31(Fragment6, { children: [
11204
- /* @__PURE__ */ jsx41(
12291
+ return hierarchy ? /* @__PURE__ */ jsxs32(Fragment6, { children: [
12292
+ /* @__PURE__ */ jsx42(
11205
12293
  HierarchyDroppableRow,
11206
12294
  {
11207
12295
  id,
@@ -11210,24 +12298,24 @@ function MatrxDataTableCore({
11210
12298
  }
11211
12299
  ),
11212
12300
  inlineDetail
11213
- ] }, id) : /* @__PURE__ */ jsxs31(Fragment6, { children: [
12301
+ ] }, id) : /* @__PURE__ */ jsxs32(Fragment6, { children: [
11214
12302
  wrappedRow,
11215
12303
  inlineDetail
11216
12304
  ] }, id);
11217
12305
  }),
11218
- appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ jsx41("tr", { "data-matrx-table-append-loading-row": true, children: /* @__PURE__ */ jsx41(
12306
+ appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ jsx42("tr", { "data-matrx-table-append-loading-row": true, children: /* @__PURE__ */ jsx42(
11219
12307
  "td",
11220
12308
  {
11221
12309
  colSpan: visibleColumns.length + leadingCols + (showActionsCol ? 1 : 0),
11222
12310
  className: "sticky bottom-0 z-20 h-16 border-y border-border bg-card/95 px-0 py-0 text-left shadow-sm backdrop-blur-sm",
11223
- children: /* @__PURE__ */ jsxs31(
12311
+ children: /* @__PURE__ */ jsxs32(
11224
12312
  "div",
11225
12313
  {
11226
12314
  role: "status",
11227
12315
  "aria-live": "polite",
11228
12316
  className: "sticky left-0 flex h-16 w-fit max-w-[100cqw] items-center justify-center gap-2 px-3 text-sm font-medium text-foreground",
11229
12317
  children: [
11230
- /* @__PURE__ */ jsx41(
12318
+ /* @__PURE__ */ jsx42(
11231
12319
  Loader2,
11232
12320
  {
11233
12321
  "aria-hidden": "true",
@@ -11241,9 +12329,9 @@ function MatrxDataTableCore({
11241
12329
  }
11242
12330
  ) }) : null
11243
12331
  ] }),
11244
- footerRows.length > 0 ? /* @__PURE__ */ jsx41("tfoot", { className: "border-t-2 border-border bg-muted/50 font-semibold", children: footerRows.map((row, index) => /* @__PURE__ */ jsxs31("tr", { children: [
11245
- selection ? /* @__PURE__ */ jsx41("td", { className: "px-2 py-2" }) : null,
11246
- visibleColumns.map((column) => /* @__PURE__ */ jsx41(
12332
+ footerRows.length > 0 ? /* @__PURE__ */ jsx42("tfoot", { className: "border-t-2 border-border bg-muted/50 font-semibold", children: footerRows.map((row, index) => /* @__PURE__ */ jsxs32("tr", { children: [
12333
+ selection ? /* @__PURE__ */ jsx42("td", { className: "px-2 py-2" }) : null,
12334
+ visibleColumns.map((column) => /* @__PURE__ */ jsx42(
11247
12335
  "td",
11248
12336
  {
11249
12337
  className: cn(
@@ -11263,7 +12351,7 @@ function MatrxDataTableCore({
11263
12351
  },
11264
12352
  columnId(column)
11265
12353
  )),
11266
- showActionsCol ? /* @__PURE__ */ jsx41("td", {}) : null
12354
+ showActionsCol ? /* @__PURE__ */ jsx42("td", {}) : null
11267
12355
  ] }, `footer-${index}`)) }) : null
11268
12356
  ]
11269
12357
  }
@@ -11271,8 +12359,8 @@ function MatrxDataTableCore({
11271
12359
  ]
11272
12360
  }
11273
12361
  ),
11274
- scrollHintLeft ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11275
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12362
+ scrollHintLeft ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12363
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11276
12364
  Button,
11277
12365
  {
11278
12366
  type: "button",
@@ -11283,13 +12371,13 @@ function MatrxDataTableCore({
11283
12371
  "data-matrx-table-scroll-control": "left",
11284
12372
  className: "absolute left-1.5 top-1/2 z-30 hidden h-11 w-11 -translate-y-1/2 rounded-full border border-glass-edge bg-glass p-0 text-foreground shadow-glass backdrop-blur-glass backdrop-saturate-glass hover:bg-glass-hover active:bg-glass-active sm:inline-flex",
11285
12373
  onClick: () => scrollTableHorizontally("left"),
11286
- children: /* @__PURE__ */ jsx41(ChevronLeft, { className: "h-5 w-5" })
12374
+ children: /* @__PURE__ */ jsx42(ChevronLeft, { className: "h-5 w-5" })
11287
12375
  }
11288
12376
  ) }),
11289
- /* @__PURE__ */ jsx41(TooltipContent, { children: "More columns to the left" })
12377
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "More columns to the left" })
11290
12378
  ] }) : null,
11291
- scrollHintRight ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11292
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12379
+ scrollHintRight ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12380
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11293
12381
  Button,
11294
12382
  {
11295
12383
  type: "button",
@@ -11300,26 +12388,26 @@ function MatrxDataTableCore({
11300
12388
  "data-matrx-table-scroll-control": "right",
11301
12389
  className: "absolute right-1.5 top-1/2 z-30 hidden h-11 w-11 -translate-y-1/2 rounded-full border border-glass-edge bg-glass p-0 text-foreground shadow-glass backdrop-blur-glass backdrop-saturate-glass hover:bg-glass-hover active:bg-glass-active sm:inline-flex",
11302
12390
  onClick: () => scrollTableHorizontally("right"),
11303
- children: /* @__PURE__ */ jsx41(ChevronRight, { className: "h-5 w-5" })
12391
+ children: /* @__PURE__ */ jsx42(ChevronRight, { className: "h-5 w-5" })
11304
12392
  }
11305
12393
  ) }),
11306
- /* @__PURE__ */ jsx41(TooltipContent, { children: "More columns to the right" })
12394
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "More columns to the right" })
11307
12395
  ] }) : null
11308
12396
  ] }),
11309
- appendQuery ? /* @__PURE__ */ jsxs31(
12397
+ appendQuery ? /* @__PURE__ */ jsxs32(
11310
12398
  "div",
11311
12399
  {
11312
12400
  "data-matrx-table-footer": true,
11313
- className: "flex min-h-11 shrink-0 flex-wrap items-center gap-0 border-t border-border",
12401
+ className: "flex min-h-8 shrink-0 flex-wrap items-center gap-2 border-t border-border",
11314
12402
  "aria-busy": isLoading || isFetching,
11315
12403
  children: [
11316
- /* @__PURE__ */ jsxs31(
12404
+ /* @__PURE__ */ jsxs32(
11317
12405
  "div",
11318
12406
  {
11319
12407
  ...isFetching && !isLoading ? {} : { role: "status", "aria-live": "polite" },
11320
- className: "flex w-full min-w-0 items-center gap-2 text-xs text-muted-foreground sm:w-auto sm:flex-1 sm:text-sm",
12408
+ className: "flex w-full min-w-0 items-center gap-2 text-xs text-muted-foreground sm:w-auto sm:flex-1",
11321
12409
  children: [
11322
- isLoading ? /* @__PURE__ */ jsx41(
12410
+ isLoading ? /* @__PURE__ */ jsx42(
11323
12411
  Loader2,
11324
12412
  {
11325
12413
  "data-matrx-table-append-loader": true,
@@ -11327,17 +12415,21 @@ function MatrxDataTableCore({
11327
12415
  className: "h-5 w-5 shrink-0 animate-spin text-primary motion-reduce:animate-none"
11328
12416
  }
11329
12417
  ) : null,
11330
- /* @__PURE__ */ jsxs31("div", { className: "min-w-0 flex-1", children: [
11331
- /* @__PURE__ */ jsx41("p", { className: "font-medium text-foreground", children: isLoading ? "Loading rows\u2026" : `${formatCount3(data.length)} loaded${appendQuery.pagination.totalItems === void 0 ? "" : ` of ${formatCount3(appendQuery.pagination.totalItems)}`}` }),
11332
- appendQuery.pagination.sourceUntil ? /* @__PURE__ */ jsxs31("p", { children: [
11333
- "Source fixed through",
11334
- " ",
11335
- new Date(appendQuery.pagination.sourceUntil).toLocaleString(),
11336
- "."
12418
+ /* @__PURE__ */ jsxs32("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-x-2", children: [
12419
+ /* @__PURE__ */ jsx42("p", { className: "min-w-0 break-words font-medium text-foreground", children: isLoading ? "Loading rows\u2026" : appendQuery.pagination.sourceRecords ? `${formatCount3(processed.length)} ${appendQuery.pagination.sourceRecords.rowLabel}${appendQuery.pagination.sourceRecords.matchedRecords === void 0 ? "" : ` (${formatCount3(appendQuery.pagination.sourceRecords.matchedRecords)} matching ${appendQuery.pagination.sourceRecords.label})`} \xB7 ${formatCount3(appendQuery.pagination.sourceRecords.loaded)}${appendQuery.pagination.sourceRecords.total === void 0 ? "" : ` / ${formatCount3(appendQuery.pagination.sourceRecords.total)}`} ${appendQuery.pagination.sourceRecords.label} loaded` : `${formatCount3(data.length)} loaded${appendQuery.pagination.totalItems === void 0 ? "" : ` of ${formatCount3(appendQuery.pagination.totalItems)}`}` }),
12420
+ appendQuery.pagination.sourceUntil || appendUsesLocalProcessing ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12421
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42("button", { type: "button", "aria-label": "Source coverage", className: "shrink-0 text-xs text-muted-foreground underline decoration-dotted underline-offset-4", children: "Source info" }) }),
12422
+ /* @__PURE__ */ jsxs32(TooltipContent, { children: [
12423
+ appendQuery.pagination.sourceUntil ? /* @__PURE__ */ jsxs32("p", { children: [
12424
+ "Source fixed through ",
12425
+ new Date(appendQuery.pagination.sourceUntil).toLocaleString(),
12426
+ "."
12427
+ ] }) : null,
12428
+ /* @__PURE__ */ jsx42("p", { children: !isLoading && !isFetching && !appendQuery.pagination.loadAll?.isLoading && !scrollPagination.error && !appendQuery.pagination.hasNextPage && appendQuery.pagination.totalItems !== void 0 && data.length === appendQuery.pagination.totalItems ? "All source rows are loaded." : appendUsesLocalProcessing ? "Local search and filters cover loaded rows." : "Source paging is active." })
12429
+ ] })
11337
12430
  ] }) : null,
11338
- !isLoading && !isFetching && !appendQuery.pagination.loadAll?.isLoading && !scrollPagination.error && !appendQuery.pagination.hasNextPage && appendQuery.pagination.totalItems !== void 0 && data.length === appendQuery.pagination.totalItems ? /* @__PURE__ */ jsx41("p", { children: "All source rows are loaded." }) : appendUsesLocalProcessing ? /* @__PURE__ */ jsx41("p", { children: "Local search and filters cover loaded rows." }) : null,
11339
- scrollPagination.error ? /* @__PURE__ */ jsx41("p", { role: "alert", className: "text-destructive", children: scrollPagination.error.message }) : null,
11340
- appendScrollPolicy?.mode === "suspended" ? /* @__PURE__ */ jsxs31("p", { role: "status", children: [
12431
+ scrollPagination.error ? /* @__PURE__ */ jsx42("p", { role: "alert", className: "text-destructive", children: scrollPagination.error.message }) : null,
12432
+ appendScrollPolicy?.mode === "suspended" ? /* @__PURE__ */ jsxs32("p", { role: "status", children: [
11341
12433
  appendScrollPolicy.reason,
11342
12434
  " Load more remains available."
11343
12435
  ] }) : null
@@ -11345,73 +12437,74 @@ function MatrxDataTableCore({
11345
12437
  ]
11346
12438
  }
11347
12439
  ),
11348
- appendQuery.pagination.sourcePageSize ? /* @__PURE__ */ jsxs31(
12440
+ appendQuery.pagination.sourcePageSize ? /* @__PURE__ */ jsxs32(
11349
12441
  Select,
11350
12442
  {
11351
12443
  value: String(appendQuery.pagination.sourcePageSize.value),
11352
12444
  onValueChange: (value) => appendQuery.pagination.sourcePageSize?.onChange(Number(value)),
11353
12445
  children: [
11354
- /* @__PURE__ */ jsx41(
12446
+ /* @__PURE__ */ jsx42(
11355
12447
  SelectTrigger,
11356
12448
  {
11357
12449
  "aria-label": "Rows per load",
11358
- className: "h-11 min-w-20 shrink-0 rounded-md border border-border bg-card px-3 text-sm [&_svg]:size-5",
12450
+ className: "h-8 min-w-20 shrink-0 rounded-md border border-border bg-card px-3 text-sm [&_svg]:size-5",
11359
12451
  disabled: isLoading || isFetching || appendQuery.pagination.loadAll?.isLoading,
11360
- children: /* @__PURE__ */ jsx41(SelectValue, {})
12452
+ children: /* @__PURE__ */ jsx42(SelectValue, {})
11361
12453
  }
11362
12454
  ),
11363
- /* @__PURE__ */ jsx41(SelectContent, { children: appendQuery.pagination.sourcePageSize.options.map((size) => /* @__PURE__ */ jsx41(SelectItem, { value: String(size), children: size }, size)) })
12455
+ /* @__PURE__ */ jsx42(SelectContent, { children: appendQuery.pagination.sourcePageSize.options.map((size) => /* @__PURE__ */ jsx42(SelectItem, { value: String(size), children: size }, size)) })
11364
12456
  ]
11365
12457
  }
11366
12458
  ) : null,
11367
- appendQuery.pagination.loadAll?.isLoading ? /* @__PURE__ */ jsx41(
12459
+ appendQuery.pagination.loadAll?.isLoading ? /* @__PURE__ */ jsx42(
11368
12460
  Button,
11369
12461
  {
11370
12462
  type: "button",
11371
12463
  variant: "outline",
11372
- className: "h-11 shrink-0 px-3 text-sm",
12464
+ className: "h-8 shrink-0 px-3 text-sm",
11373
12465
  onClick: appendQuery.pagination.loadAll.stop,
11374
12466
  children: "Stop loading"
11375
12467
  }
11376
- ) : scrollPagination.error ? /* @__PURE__ */ jsx41(
12468
+ ) : scrollPagination.error ? /* @__PURE__ */ jsx42(
11377
12469
  Button,
11378
12470
  {
11379
12471
  type: "button",
11380
12472
  variant: "outline",
11381
- className: "h-11 shrink-0 px-3 text-sm",
12473
+ className: "h-8 shrink-0 px-3 text-sm",
11382
12474
  onClick: appendQuery.pagination.retrySource ?? (appendQuery.pagination.hasNextPage ? appendQuery.pagination.loadNextPage : appendQuery.pagination.refresh),
11383
12475
  children: appendQuery.pagination.retrySource ? "Retry source" : appendQuery.pagination.hasNextPage ? "Retry" : "Reload rows"
11384
12476
  }
11385
- ) : appendQuery.pagination.hasNextPage || scrollPagination.error ? /* @__PURE__ */ jsxs31("div", { className: "flex min-w-0 max-w-full flex-wrap gap-0", children: [
11386
- /* @__PURE__ */ jsx41(
12477
+ ) : appendQuery.pagination.hasNextPage || scrollPagination.error ? /* @__PURE__ */ jsxs32("div", { className: "flex min-w-0 max-w-full flex-wrap gap-0", children: [
12478
+ /* @__PURE__ */ jsx42(
11387
12479
  Button,
11388
12480
  {
11389
12481
  type: "button",
11390
12482
  variant: "outline",
11391
- className: "h-11 px-3 text-sm",
12483
+ className: "h-8 px-3 text-sm",
11392
12484
  disabled: isLoading || isFetching,
11393
12485
  onClick: () => void scrollPagination.requestNextPage(),
11394
12486
  children: "Load more"
11395
12487
  }
11396
12488
  ),
11397
- appendQuery.pagination.loadAll ? /* @__PURE__ */ jsx41(
12489
+ appendQuery.pagination.loadAll ? /* @__PURE__ */ jsx42(
11398
12490
  Button,
11399
12491
  {
11400
12492
  type: "button",
11401
12493
  variant: "ghost",
11402
- className: "h-11 px-3 text-sm",
12494
+ className: "h-8 px-3 text-sm",
11403
12495
  disabled: isLoading || isFetching,
11404
12496
  onClick: appendQuery.pagination.loadAll.request,
11405
12497
  children: "Load all"
11406
12498
  }
11407
12499
  ) : null
11408
- ] }) : !isLoading && appendQuery.pagination.totalItems !== void 0 && data.length === appendQuery.pagination.totalItems ? /* @__PURE__ */ jsx41("span", { className: "min-w-0 max-w-full break-words whitespace-normal px-3 text-xs text-muted-foreground sm:text-sm", children: "All rows loaded" }) : null
12500
+ ] }) : !isLoading && appendQuery.pagination.totalItems !== void 0 && data.length === appendQuery.pagination.totalItems ? /* @__PURE__ */ jsx42("span", { className: "min-w-0 max-w-full break-words whitespace-normal px-3 text-xs text-muted-foreground sm:text-sm", children: "All rows loaded" }) : null
11409
12501
  ]
11410
12502
  }
11411
- ) : !hidePagination && totalItems > 0 ? /* @__PURE__ */ jsx41("div", { className: "shrink-0", children: /* @__PURE__ */ jsx41(
12503
+ ) : !hidePagination && (totalItems > 0 || sourceTotal !== void 0) ? /* @__PURE__ */ jsx42("div", { className: "shrink-0", children: /* @__PURE__ */ jsx42(
11412
12504
  GenericTablePagination,
11413
12505
  {
11414
12506
  totalItems,
12507
+ ...sourceTotal === void 0 ? {} : { labelFormat: (start, end, total) => `${formatCount3(start)}\u2013${formatCount3(end)} of ${formatCount3(total)} matching \xB7 ${formatCount3(data.length)} / ${formatCount3(sourceTotal)} loaded` },
11415
12508
  ...localProgressiveEnabled ? { progressive: {
11416
12509
  shownCount: progressiveRows.shownCount,
11417
12510
  loadedCount: data.length,
@@ -11434,7 +12527,7 @@ function MatrxDataTableCore({
11434
12527
  }
11435
12528
  ) }) : null
11436
12529
  ] }),
11437
- /* @__PURE__ */ jsx41(
12530
+ /* @__PURE__ */ jsx42(
11438
12531
  ColumnManager,
11439
12532
  {
11440
12533
  open: columnManagerOpen,
@@ -11445,7 +12538,7 @@ function MatrxDataTableCore({
11445
12538
  onApply: commitColumnState
11446
12539
  }
11447
12540
  ),
11448
- detailEnabled && selectedRow ? /* @__PURE__ */ jsx41(
12541
+ detailEnabled && selectedRow ? /* @__PURE__ */ jsx42(
11449
12542
  SidePanelSurface,
11450
12543
  {
11451
12544
  title: resolveStringTitle(
@@ -11456,8 +12549,8 @@ function MatrxDataTableCore({
11456
12549
  description: detail?.description?.(selectedRow),
11457
12550
  onClose: () => setSelectedId(null),
11458
12551
  defaultWidth: detail?.defaultWidth ?? 480,
11459
- headerActions: /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-1", children: [
11460
- effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx41(
12552
+ headerActions: /* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-1", children: [
12553
+ effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx42(
11461
12554
  TableRowCopyControl,
11462
12555
  {
11463
12556
  size: "icon",
@@ -11469,8 +12562,8 @@ function MatrxDataTableCore({
11469
12562
  }
11470
12563
  ) : null,
11471
12564
  detail?.headerActions?.(selectedRow),
11472
- windowEnabled ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11473
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12565
+ windowEnabled ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12566
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11474
12567
  Button,
11475
12568
  {
11476
12569
  type: "button",
@@ -11480,10 +12573,10 @@ function MatrxDataTableCore({
11480
12573
  className: "h-7 w-7",
11481
12574
  "aria-label": "Open in window",
11482
12575
  onClick: () => openWindow(selectedRow),
11483
- children: /* @__PURE__ */ jsx41(PanelRight, { className: "h-5 w-5" })
12576
+ children: /* @__PURE__ */ jsx42(PanelRight, { className: "h-5 w-5" })
11484
12577
  }
11485
12578
  ) }),
11486
- /* @__PURE__ */ jsx41(TooltipContent, { children: "Open in window" })
12579
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "Open in window" })
11487
12580
  ] }) : null
11488
12581
  ] }),
11489
12582
  children: detail?.render ? (
@@ -11494,7 +12587,7 @@ function MatrxDataTableCore({
11494
12587
  // fixes the whole class at once — a custom body that already
11495
12588
  // scrolls (`h-full` + `overflow-y-auto` root) still resolves to
11496
12589
  // this container's height, so no second scrollbar appears.
11497
- /* @__PURE__ */ jsx41("div", { className: "h-full min-h-0 overflow-y-auto", children: detail.render(selectedRow, {
12590
+ /* @__PURE__ */ jsx42("div", { className: "h-full min-h-0 overflow-y-auto", children: detail.render(selectedRow, {
11498
12591
  closeDetail: () => setSelectedId(null),
11499
12592
  openDetail: () => openDetail(selectedRow),
11500
12593
  openWindow: () => openWindow(selectedRow),
@@ -11502,7 +12595,7 @@ function MatrxDataTableCore({
11502
12595
  hasPendingEdits: Boolean(edits[getRowId(selectedRow)]),
11503
12596
  discardPendingEdits: () => discardRowEdits(getRowId(selectedRow))
11504
12597
  }) })
11505
- ) : /* @__PURE__ */ jsx41(
12598
+ ) : /* @__PURE__ */ jsx42(
11506
12599
  DataRowInspector,
11507
12600
  {
11508
12601
  row: selectedRow,
@@ -11514,7 +12607,7 @@ function MatrxDataTableCore({
11514
12607
  )
11515
12608
  }
11516
12609
  ) : null,
11517
- windowRow ? /* @__PURE__ */ jsx41(
12610
+ windowRow ? /* @__PURE__ */ jsx42(
11518
12611
  DataRowWindow,
11519
12612
  {
11520
12613
  isOpen: true,
@@ -11525,9 +12618,9 @@ function MatrxDataTableCore({
11525
12618
  height: windowConfig?.height,
11526
12619
  windowId: `matrx-data-row-${urlState?.id ?? "local"}-${getRowId(windowRow)}`,
11527
12620
  defaultTab: windowConfig?.defaultTab,
11528
- headerActions: /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-1", children: [
11529
- windowConfig?.openOnRowClick === true && detail?.enabled === true ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11530
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12621
+ headerActions: /* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-1", children: [
12622
+ windowConfig?.openOnRowClick === true && detail?.enabled === true ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12623
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11531
12624
  Button,
11532
12625
  {
11533
12626
  type: "button",
@@ -11540,12 +12633,12 @@ function MatrxDataTableCore({
11540
12633
  closeWindow();
11541
12634
  openDetail(windowRow);
11542
12635
  },
11543
- children: /* @__PURE__ */ jsx41(PanelRightOpen, { className: "h-5 w-5" })
12636
+ children: /* @__PURE__ */ jsx42(PanelRightOpen, { className: "h-5 w-5" })
11544
12637
  }
11545
12638
  ) }),
11546
- /* @__PURE__ */ jsx41(TooltipContent, { children: "Open in side panel" })
12639
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "Open in side panel" })
11547
12640
  ] }) : null,
11548
- effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx41(
12641
+ effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx42(
11549
12642
  TableRowCopyControl,
11550
12643
  {
11551
12644
  size: "icon",
@@ -11564,7 +12657,7 @@ function MatrxDataTableCore({
11564
12657
  closeWindow,
11565
12658
  hasPendingEdits: Boolean(edits[getRowId(windowRow)]),
11566
12659
  discardPendingEdits: () => discardRowEdits(getRowId(windowRow))
11567
- }) ?? /* @__PURE__ */ jsx41(
12660
+ }) ?? /* @__PURE__ */ jsx42(
11568
12661
  DataRowInspector,
11569
12662
  {
11570
12663
  row: windowRow,
@@ -11600,15 +12693,15 @@ function MatrxDataTableCore({
11600
12693
  })
11601
12694
  }
11602
12695
  ) : null,
11603
- editEnabled ? /* @__PURE__ */ jsxs31(Fragment7, { children: [
11604
- foreignDrafts.length > 0 ? /* @__PURE__ */ jsxs31(
12696
+ editEnabled ? /* @__PURE__ */ jsxs32(Fragment7, { children: [
12697
+ foreignDrafts.length > 0 ? /* @__PURE__ */ jsxs32(
11605
12698
  "div",
11606
12699
  {
11607
12700
  "data-matrx-foreign-drafts": true,
11608
12701
  className: "fixed inset-x-3 bottom-20 z-50 flex flex-wrap items-center justify-center gap-2 rounded-lg border border-amber-500/40 bg-card px-3 py-2 text-xs shadow-lg sm:inset-x-auto sm:left-1/2 sm:-translate-x-1/2 sm:flex-nowrap",
11609
12702
  children: [
11610
- /* @__PURE__ */ jsx41("span", { children: "Unsaved edits from previous results" }),
11611
- /* @__PURE__ */ jsx41(
12703
+ /* @__PURE__ */ jsx42("span", { children: "Unsaved edits from previous results" }),
12704
+ /* @__PURE__ */ jsx42(
11612
12705
  CopyButtons,
11613
12706
  {
11614
12707
  size: "xs",
@@ -11617,11 +12710,11 @@ function MatrxDataTableCore({
11617
12710
  json: () => foreignDraftPayload
11618
12711
  }
11619
12712
  ),
11620
- /* @__PURE__ */ jsx41(Button, { type: "button", size: "sm", variant: "ghost", className: "h-7 text-xs text-destructive", onClick: () => setConfirmForeignDraftDiscard(true), children: "Discard drafts" })
12713
+ /* @__PURE__ */ jsx42(Button, { type: "button", size: "sm", variant: "ghost", className: "h-7 text-xs text-destructive", onClick: () => setConfirmForeignDraftDiscard(true), children: "Discard drafts" })
11621
12714
  ]
11622
12715
  }
11623
12716
  ) : null,
11624
- /* @__PURE__ */ jsx41(
12717
+ /* @__PURE__ */ jsx42(
11625
12718
  ConfirmDialog,
11626
12719
  {
11627
12720
  open: confirmForeignDraftDiscard,
@@ -11641,7 +12734,7 @@ function MatrxDataTableCore({
11641
12734
  }
11642
12735
  }
11643
12736
  ),
11644
- /* @__PURE__ */ jsx41(
12737
+ /* @__PURE__ */ jsx42(
11645
12738
  DirtySavePill,
11646
12739
  {
11647
12740
  changeCount,
@@ -11654,11 +12747,11 @@ function MatrxDataTableCore({
11654
12747
  ]
11655
12748
  }
11656
12749
  ),
11657
- /* @__PURE__ */ jsx41(DragOverlay, { children: draggedRow ? (
12750
+ /* @__PURE__ */ jsx42(DragOverlay, { children: draggedRow ? (
11658
12751
  // w-max: the overlay inherits the ACTIVE node's size, and the active
11659
12752
  // node is the 16px grip handle — without it the label wraps to one
11660
12753
  // character per line.
11661
- /* @__PURE__ */ jsx41("div", { className: "w-max max-w-xs truncate rounded border border-border bg-card px-2.5 py-1.5 text-sm font-medium text-foreground shadow-md", children: hierarchy?.itemLabel?.(draggedRow) ?? "Moving row" })
12754
+ /* @__PURE__ */ jsx42("div", { className: "w-max max-w-xs truncate rounded border border-border bg-card px-2.5 py-1.5 text-sm font-medium text-foreground shadow-md", children: hierarchy?.itemLabel?.(draggedRow) ?? "Moving row" })
11662
12755
  ) : null })
11663
12756
  ]
11664
12757
  }
@@ -11673,7 +12766,7 @@ function HierarchyDragHandle({
11673
12766
  id,
11674
12767
  disabled
11675
12768
  });
11676
- return /* @__PURE__ */ jsx41(
12769
+ return /* @__PURE__ */ jsx42(
11677
12770
  "button",
11678
12771
  {
11679
12772
  ref: setNodeRef,
@@ -11685,7 +12778,7 @@ function HierarchyDragHandle({
11685
12778
  onClick: (event) => event.stopPropagation(),
11686
12779
  ...attributes,
11687
12780
  ...listeners,
11688
- children: /* @__PURE__ */ jsx41(GripVertical, { className: "h-3.5 w-3.5" })
12781
+ children: /* @__PURE__ */ jsx42(GripVertical, { className: "h-3.5 w-3.5" })
11689
12782
  }
11690
12783
  );
11691
12784
  }
@@ -11694,7 +12787,7 @@ function HierarchyRootDropTarget({
11694
12787
  draggedLabel
11695
12788
  }) {
11696
12789
  const { isOver, setNodeRef } = useDroppable2({ id: "__root__" });
11697
- return /* @__PURE__ */ jsxs31(
12790
+ return /* @__PURE__ */ jsxs32(
11698
12791
  "div",
11699
12792
  {
11700
12793
  ref: setNodeRef,
@@ -11704,8 +12797,8 @@ function HierarchyRootDropTarget({
11704
12797
  isOver && "border-solid bg-primary/20 shadow-md shadow-primary/25"
11705
12798
  ),
11706
12799
  children: [
11707
- /* @__PURE__ */ jsx41("span", { className: "truncate", children: draggedLabel }),
11708
- /* @__PURE__ */ jsx41("span", { className: "text-primary/75", children: label })
12800
+ /* @__PURE__ */ jsx42("span", { className: "truncate", children: draggedLabel }),
12801
+ /* @__PURE__ */ jsx42("span", { className: "text-primary/75", children: label })
11709
12802
  ]
11710
12803
  }
11711
12804
  );
@@ -11754,7 +12847,7 @@ function HierarchyDragIndicatorLayer({
11754
12847
  const { preview: preview2 } = indicator;
11755
12848
  const indent = indicator.left + 10 + preview2.depth * 12;
11756
12849
  if (preview2.position === "inside") {
11757
- return /* @__PURE__ */ jsx41(
12850
+ return /* @__PURE__ */ jsx42(
11758
12851
  "div",
11759
12852
  {
11760
12853
  "aria-hidden": "true",
@@ -11766,7 +12859,7 @@ function HierarchyDragIndicatorLayer({
11766
12859
  width: Math.max(0, indicator.width - 4),
11767
12860
  height: indicator.height
11768
12861
  },
11769
- children: /* @__PURE__ */ jsxs31(
12862
+ children: /* @__PURE__ */ jsxs32(
11770
12863
  "span",
11771
12864
  {
11772
12865
  className: "absolute top-1/2 -translate-y-1/2 whitespace-nowrap rounded bg-card/95 px-1.5 py-0.5 text-[10px] font-medium text-primary",
@@ -11781,7 +12874,7 @@ function HierarchyDragIndicatorLayer({
11781
12874
  );
11782
12875
  }
11783
12876
  const lineTop = preview2.position === "before" ? indicator.top - 1 : indicator.top + indicator.height - 1;
11784
- return /* @__PURE__ */ jsx41(
12877
+ return /* @__PURE__ */ jsx42(
11785
12878
  "div",
11786
12879
  {
11787
12880
  "aria-hidden": "true",
@@ -11792,9 +12885,9 @@ function HierarchyDragIndicatorLayer({
11792
12885
  left: indent,
11793
12886
  width: Math.max(0, indicator.left + indicator.width - indent - 8)
11794
12887
  },
11795
- children: /* @__PURE__ */ jsxs31("div", { className: "relative h-0.5 rounded-full bg-primary", children: [
11796
- /* @__PURE__ */ jsx41("span", { className: "absolute -left-1 top-1/2 h-2 w-2 -translate-y-1/2 rounded-full border-2 border-primary bg-card" }),
11797
- /* @__PURE__ */ jsxs31(
12888
+ children: /* @__PURE__ */ jsxs32("div", { className: "relative h-0.5 rounded-full bg-primary", children: [
12889
+ /* @__PURE__ */ jsx42("span", { className: "absolute -left-1 top-1/2 h-2 w-2 -translate-y-1/2 rounded-full border-2 border-primary bg-card" }),
12890
+ /* @__PURE__ */ jsxs32(
11798
12891
  "span",
11799
12892
  {
11800
12893
  className: cn(
@@ -11835,7 +12928,7 @@ function ColumnHeaderDropZone({
11835
12928
  disabled: !enabled,
11836
12929
  data: { matrxDragKind: "column-header", columnId: id }
11837
12930
  });
11838
- return /* @__PURE__ */ jsx41("div", { ref: setNodeRef, className: "flex min-w-0 items-center", children });
12931
+ return /* @__PURE__ */ jsx42("div", { ref: setNodeRef, className: "flex min-w-0 items-center", children });
11839
12932
  }
11840
12933
  function fixedUtilityWidth(width) {
11841
12934
  return width === void 0 ? void 0 : { width: `${width}px`, minWidth: `${width}px`, maxWidth: `${width}px` };
@@ -11869,9 +12962,9 @@ function DefaultJsonCell({ value }) {
11869
12962
  const Viewer = host.JsonViewer;
11870
12963
  const text = JSON.stringify(value, null, 2);
11871
12964
  const summary = Array.isArray(value) ? `${value.length} items` : Object.keys(value).slice(0, 3).join(", ") || "Empty object";
11872
- return /* @__PURE__ */ jsxs31(Fragment7, { children: [
11873
- /* @__PURE__ */ jsxs31(Tooltip, { children: [
11874
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs31("button", { type: "button", className: "block max-w-full truncate text-left text-sm text-foreground", onClick: (event) => {
12965
+ return /* @__PURE__ */ jsxs32(Fragment7, { children: [
12966
+ /* @__PURE__ */ jsxs32(Tooltip, { children: [
12967
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs32("button", { type: "button", className: "block max-w-full truncate text-left text-sm text-foreground", onClick: (event) => {
11875
12968
  event.stopPropagation();
11876
12969
  setOpen(true);
11877
12970
  }, style: { display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden", whiteSpace: "normal", overflowWrap: "anywhere" }, "aria-label": "Open JSON value", children: [
@@ -11879,9 +12972,9 @@ function DefaultJsonCell({ value }) {
11879
12972
  " ",
11880
12973
  summary
11881
12974
  ] }) }),
11882
- /* @__PURE__ */ jsx41(TooltipContent, { className: "max-w-md max-h-80 overflow-auto whitespace-pre-wrap break-words", children: text })
12975
+ /* @__PURE__ */ jsx42(TooltipContent, { className: "max-w-md max-h-80 overflow-auto whitespace-pre-wrap break-words", children: text })
11883
12976
  ] }),
11884
- /* @__PURE__ */ jsx41(DataRowWindow, { isOpen: open, onClose: () => setOpen(false), title: "JSON value", row: value, viewContent: Viewer ? /* @__PURE__ */ jsx41(Viewer, { data: value }) : /* @__PURE__ */ jsx41("pre", { className: "overflow-auto whitespace-pre-wrap p-3 text-xs", children: text }) })
12977
+ /* @__PURE__ */ jsx42(DataRowWindow, { isOpen: open, onClose: () => setOpen(false), title: "JSON value", row: value, viewContent: Viewer ? /* @__PURE__ */ jsx42(Viewer, { data: value }) : /* @__PURE__ */ jsx42("pre", { className: "overflow-auto whitespace-pre-wrap p-3 text-xs", children: text }) })
11885
12978
  ] });
11886
12979
  }
11887
12980
  function DefaultMarkerCell({
@@ -11890,8 +12983,8 @@ function DefaultMarkerCell({
11890
12983
  }) {
11891
12984
  const label = marker === "favorite" ? value ? "Favorite" : "Not favorite" : value ? "Pinned" : "Not pinned";
11892
12985
  const Icon3 = marker === "favorite" ? Star : Pin;
11893
- return /* @__PURE__ */ jsxs31(Tooltip, { children: [
11894
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12986
+ return /* @__PURE__ */ jsxs32(Tooltip, { children: [
12987
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11895
12988
  "span",
11896
12989
  {
11897
12990
  role: "img",
@@ -11900,21 +12993,23 @@ function DefaultMarkerCell({
11900
12993
  "inline-flex size-5 items-center justify-center",
11901
12994
  value ? "text-amber-500" : "text-muted-foreground/45"
11902
12995
  ),
11903
- children: /* @__PURE__ */ jsx41(Icon3, { className: "size-4", ...value ? { fill: "currentColor" } : {} })
12996
+ children: /* @__PURE__ */ jsx42(Icon3, { className: "size-4", ...value ? { fill: "currentColor" } : {} })
11904
12997
  }
11905
12998
  ) }),
11906
- /* @__PURE__ */ jsx41(TooltipContent, { children: label })
12999
+ /* @__PURE__ */ jsx42(TooltipContent, { children: label })
11907
13000
  ] });
11908
13001
  }
11909
13002
  function renderCell(row, col, index) {
11910
13003
  if (col.cell) return col.cell(row, index);
11911
13004
  const raw = getCellValue(row, col);
13005
+ const formattedByDeclaration = formatColumnValue(col, raw);
13006
+ if (formattedByDeclaration) return /* @__PURE__ */ jsx42(FormattedCell, { result: formattedByDeclaration });
11912
13007
  const kind = col.cellKind ?? "auto";
11913
13008
  const asUuid = kind === "uuid" || kind === "fk" || kind === "auto" && isUuidValue(raw);
11914
13009
  if (asUuid && typeof raw === "string") {
11915
13010
  const forbidden = typeof col.fk?.forbidden === "function" ? col.fk.forbidden(raw, row) : Boolean(col.fk?.forbidden);
11916
13011
  const declaredToken = typeof col.fk?.token === "function" ? col.fk.token(row) : col.fk?.token;
11917
- return /* @__PURE__ */ jsx41(
13012
+ return /* @__PURE__ */ jsx42(
11918
13013
  MatrxUuidCell,
11919
13014
  {
11920
13015
  value: raw,
@@ -11926,16 +13021,16 @@ function renderCell(row, col, index) {
11926
13021
  }
11927
13022
  );
11928
13023
  }
11929
- if (raw !== null && typeof raw === "object" && !(raw instanceof Date)) return /* @__PURE__ */ jsx41(DefaultJsonCell, { value: raw });
13024
+ if (raw !== null && typeof raw === "object" && !(raw instanceof Date)) return /* @__PURE__ */ jsx42(DefaultJsonCell, { value: raw });
11930
13025
  if (typeof raw === "boolean") {
11931
13026
  const marker = resolveColumnMarker(col);
11932
- if (marker) return /* @__PURE__ */ jsx41(DefaultMarkerCell, { marker, value: raw });
11933
- return /* @__PURE__ */ jsx41("span", { className: raw ? "rounded bg-emerald-500/10 px-1.5 py-0.5 text-xs text-emerald-600" : "rounded bg-slate-500/10 px-1.5 py-0.5 text-xs text-muted-foreground", children: raw ? "Yes" : "No" });
13027
+ if (marker) return /* @__PURE__ */ jsx42(DefaultMarkerCell, { marker, value: raw });
13028
+ return /* @__PURE__ */ jsx42("span", { className: raw ? "rounded bg-emerald-500/10 px-1.5 py-0.5 text-xs text-emerald-600" : "rounded bg-slate-500/10 px-1.5 py-0.5 text-xs text-muted-foreground", children: raw ? "Yes" : "No" });
11934
13029
  }
11935
13030
  const formatted = formatTableDisplayValue(raw);
11936
- return /* @__PURE__ */ jsxs31(Tooltip, { children: [
11937
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41("span", { className: "block text-sm text-foreground", style: { display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden", overflowWrap: "anywhere" }, children: formatted }) }),
11938
- /* @__PURE__ */ jsx41(TooltipContent, { className: "max-w-md whitespace-pre-wrap break-words max-h-80 overflow-auto", children: typeof raw === "object" && raw !== null ? JSON.stringify(raw, null, 2) : formatted })
13031
+ return /* @__PURE__ */ jsxs32(Tooltip, { children: [
13032
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42("span", { className: "block text-sm text-foreground", style: { display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden", overflowWrap: "anywhere" }, children: formatted }) }),
13033
+ /* @__PURE__ */ jsx42(TooltipContent, { className: "max-w-md whitespace-pre-wrap break-words max-h-80 overflow-auto", children: typeof raw === "object" && raw !== null ? JSON.stringify(raw, null, 2) : formatted })
11939
13034
  ] });
11940
13035
  }
11941
13036
  function resolveStringTitle(title, fallback) {
@@ -11950,14 +13045,14 @@ import { useId as useId3, useState as useState22 } from "react";
11950
13045
  // src/dropdown-menu.tsx
11951
13046
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
11952
13047
  import * as React17 from "react";
11953
- import { jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
13048
+ import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
11954
13049
  var DropdownMenu = DropdownMenuPrimitive.Root;
11955
13050
  var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
11956
13051
  var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
11957
13052
  var MENU_SURFACE_CLASS = "z-[10001] min-w-[8rem] max-h-[var(--radix-dropdown-menu-content-available-height)] overflow-y-auto overflow-x-hidden overscroll-contain rounded-md border bg-popover p-1 text-popover-foreground";
11958
13053
  var MENU_ITEM_CLASS = "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
11959
13054
  var MENU_INDICATOR_ITEM_CLASS = "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
11960
- var DropdownMenuSubTrigger = React17.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs32(
13055
+ var DropdownMenuSubTrigger = React17.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs33(
11961
13056
  DropdownMenuPrimitive.SubTrigger,
11962
13057
  {
11963
13058
  ref,
@@ -11970,12 +13065,12 @@ var DropdownMenuSubTrigger = React17.forwardRef(({ className, inset, children, .
11970
13065
  ...props,
11971
13066
  children: [
11972
13067
  children,
11973
- /* @__PURE__ */ jsx42(RadixChevronRightIcon, { className: "ml-auto h-4 w-4" })
13068
+ /* @__PURE__ */ jsx43(RadixChevronRightIcon, { className: "ml-auto h-4 w-4" })
11974
13069
  ]
11975
13070
  }
11976
13071
  ));
11977
13072
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
11978
- var DropdownMenuSubContent = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx42(
13073
+ var DropdownMenuSubContent = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx43(
11979
13074
  DropdownMenuPrimitive.SubContent,
11980
13075
  {
11981
13076
  ref,
@@ -11987,7 +13082,7 @@ var DropdownMenuSubContent = React17.forwardRef(({ className, ...props }, ref) =
11987
13082
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
11988
13083
  var DropdownMenuContent = React17.forwardRef(({ className, sideOffset = 4, container, ...props }, ref) => {
11989
13084
  const portalContainer = usePortalContainer(container);
11990
- return /* @__PURE__ */ jsx42(DropdownMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx42(
13085
+ return /* @__PURE__ */ jsx43(DropdownMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx43(
11991
13086
  DropdownMenuPrimitive.Content,
11992
13087
  {
11993
13088
  ref,
@@ -12004,7 +13099,7 @@ var DropdownMenuContent = React17.forwardRef(({ className, sideOffset = 4, conta
12004
13099
  ) });
12005
13100
  });
12006
13101
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
12007
- var DropdownMenuItem = React17.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx42(
13102
+ var DropdownMenuItem = React17.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx43(
12008
13103
  DropdownMenuPrimitive.Item,
12009
13104
  {
12010
13105
  ref,
@@ -12014,7 +13109,7 @@ var DropdownMenuItem = React17.forwardRef(({ className, inset, ...props }, ref)
12014
13109
  }
12015
13110
  ));
12016
13111
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
12017
- var DropdownMenuCheckboxItem = React17.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs32(
13112
+ var DropdownMenuCheckboxItem = React17.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs33(
12018
13113
  DropdownMenuPrimitive.CheckboxItem,
12019
13114
  {
12020
13115
  ref,
@@ -12022,13 +13117,13 @@ var DropdownMenuCheckboxItem = React17.forwardRef(({ className, children, ...pro
12022
13117
  className: cn(MENU_INDICATOR_ITEM_CLASS, className),
12023
13118
  ...props,
12024
13119
  children: [
12025
- /* @__PURE__ */ jsx42("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx42(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx42(CheckIcon, { className: "h-4 w-4" }) }) }),
13120
+ /* @__PURE__ */ jsx43("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx43(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx43(CheckIcon, { className: "h-4 w-4" }) }) }),
12026
13121
  children
12027
13122
  ]
12028
13123
  }
12029
13124
  ));
12030
13125
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
12031
- var DropdownMenuRadioItem = React17.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs32(
13126
+ var DropdownMenuRadioItem = React17.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs33(
12032
13127
  DropdownMenuPrimitive.RadioItem,
12033
13128
  {
12034
13129
  ref,
@@ -12036,13 +13131,13 @@ var DropdownMenuRadioItem = React17.forwardRef(({ className, children, ...props
12036
13131
  className: cn(MENU_INDICATOR_ITEM_CLASS, className),
12037
13132
  ...props,
12038
13133
  children: [
12039
- /* @__PURE__ */ jsx42("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx42(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx42(DotFilledIcon, { className: "h-4 w-4 fill-current" }) }) }),
13134
+ /* @__PURE__ */ jsx43("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx43(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx43(DotFilledIcon, { className: "h-4 w-4 fill-current" }) }) }),
12040
13135
  children
12041
13136
  ]
12042
13137
  }
12043
13138
  ));
12044
13139
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
12045
- var DropdownMenuLabel = React17.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx42(
13140
+ var DropdownMenuLabel = React17.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx43(
12046
13141
  DropdownMenuPrimitive.Label,
12047
13142
  {
12048
13143
  ref,
@@ -12052,7 +13147,7 @@ var DropdownMenuLabel = React17.forwardRef(({ className, inset, ...props }, ref)
12052
13147
  }
12053
13148
  ));
12054
13149
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
12055
- var DropdownMenuSeparator = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx42(
13150
+ var DropdownMenuSeparator = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx43(
12056
13151
  DropdownMenuPrimitive.Separator,
12057
13152
  {
12058
13153
  ref,
@@ -12065,7 +13160,7 @@ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
12065
13160
  var DropdownMenuShortcut = ({
12066
13161
  className,
12067
13162
  ...props
12068
- }) => /* @__PURE__ */ jsx42(
13163
+ }) => /* @__PURE__ */ jsx43(
12069
13164
  "span",
12070
13165
  {
12071
13166
  "data-slot": "dropdown-menu-shortcut",
@@ -12076,7 +13171,7 @@ var DropdownMenuShortcut = ({
12076
13171
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
12077
13172
 
12078
13173
  // src/data-table/SavedViewsControl.tsx
12079
- import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
13174
+ import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
12080
13175
  function SavedViewsControl({
12081
13176
  views,
12082
13177
  activeId = null,
@@ -12134,10 +13229,10 @@ function SavedViewsControl({
12134
13229
  }
12135
13230
  };
12136
13231
  const activeName = activeId ? views.find((view) => view.id === activeId)?.name : void 0;
12137
- return /* @__PURE__ */ jsxs33("div", { className: "flex min-w-0 flex-wrap items-center gap-1", "data-matrx-table-saved-views": true, children: [
12138
- /* @__PURE__ */ jsxs33(DropdownMenu, { children: [
12139
- /* @__PURE__ */ jsxs33(Tooltip, { children: [
12140
- /* @__PURE__ */ jsx43(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx43(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs33(
13232
+ return /* @__PURE__ */ jsxs34("div", { className: "flex min-w-0 flex-wrap items-center gap-1", "data-matrx-table-saved-views": true, children: [
13233
+ /* @__PURE__ */ jsxs34(DropdownMenu, { children: [
13234
+ /* @__PURE__ */ jsxs34(Tooltip, { children: [
13235
+ /* @__PURE__ */ jsx44(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx44(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs34(
12141
13236
  Button,
12142
13237
  {
12143
13238
  type: "button",
@@ -12148,38 +13243,38 @@ function SavedViewsControl({
12148
13243
  "aria-describedby": dirty ? unsavedChangesId : void 0,
12149
13244
  disabled: saving,
12150
13245
  children: [
12151
- /* @__PURE__ */ jsx43("span", { className: "min-w-0 flex-1 truncate", children: loading ? "Loading views\u2026" : activeName ?? "Default view" }),
12152
- dirty ? /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: "size-1.5 shrink-0 rounded-full bg-amber-500" }) : null,
12153
- /* @__PURE__ */ jsx43(ChevronDown, { className: "size-3.5 shrink-0" })
13246
+ /* @__PURE__ */ jsx44("span", { className: "min-w-0 flex-1 truncate", children: loading ? "Loading views\u2026" : activeName ?? "Default view" }),
13247
+ dirty ? /* @__PURE__ */ jsx44("span", { "aria-hidden": "true", className: "size-1.5 shrink-0 rounded-full bg-amber-500" }) : null,
13248
+ /* @__PURE__ */ jsx44(ChevronDown, { className: "size-3.5 shrink-0" })
12154
13249
  ]
12155
13250
  }
12156
13251
  ) }) }),
12157
- /* @__PURE__ */ jsx43(TooltipContent, { children: "Choose or save a table view" })
13252
+ /* @__PURE__ */ jsx44(TooltipContent, { children: "Choose or save a table view" })
12158
13253
  ] }),
12159
- /* @__PURE__ */ jsxs33(DropdownMenuContent, { align: "end", children: [
12160
- /* @__PURE__ */ jsx43(DropdownMenuLabel, { children: "Views" }),
12161
- /* @__PURE__ */ jsxs33(DropdownMenuRadioGroup, { value: activeId ?? "__default__", onValueChange: (value) => onSelect(value === "__default__" ? null : value), children: [
12162
- /* @__PURE__ */ jsx43(DropdownMenuRadioItem, { value: "__default__", children: "Default view" }),
12163
- views.map((view) => /* @__PURE__ */ jsx43(DropdownMenuRadioItem, { value: view.id, children: view.name }, view.id))
13254
+ /* @__PURE__ */ jsxs34(DropdownMenuContent, { align: "end", children: [
13255
+ /* @__PURE__ */ jsx44(DropdownMenuLabel, { children: "Views" }),
13256
+ /* @__PURE__ */ jsxs34(DropdownMenuRadioGroup, { value: activeId ?? "__default__", onValueChange: (value) => onSelect(value === "__default__" ? null : value), children: [
13257
+ /* @__PURE__ */ jsx44(DropdownMenuRadioItem, { value: "__default__", children: "Default view" }),
13258
+ views.map((view) => /* @__PURE__ */ jsx44(DropdownMenuRadioItem, { value: view.id, children: view.name }, view.id))
12164
13259
  ] }),
12165
- /* @__PURE__ */ jsx43(DropdownMenuSeparator, {}),
12166
- /* @__PURE__ */ jsx43(DropdownMenuItem, { disabled: saving, onSelect: () => {
13260
+ /* @__PURE__ */ jsx44(DropdownMenuSeparator, {}),
13261
+ /* @__PURE__ */ jsx44(DropdownMenuItem, { disabled: saving, onSelect: () => {
12167
13262
  setActionError(null);
12168
13263
  setSaveOpen(true);
12169
13264
  }, children: "Save current view\u2026" }),
12170
- activeId && onUpdate ? /* @__PURE__ */ jsx43(DropdownMenuItem, { disabled: saving, onSelect: () => void update(), children: "Update current view" }) : null,
12171
- onReload ? /* @__PURE__ */ jsx43(DropdownMenuItem, { disabled: saving || loading, onSelect: () => void reload(), children: "Reload views" }) : null
13265
+ activeId && onUpdate ? /* @__PURE__ */ jsx44(DropdownMenuItem, { disabled: saving, onSelect: () => void update(), children: "Update current view" }) : null,
13266
+ onReload ? /* @__PURE__ */ jsx44(DropdownMenuItem, { disabled: saving || loading, onSelect: () => void reload(), children: "Reload views" }) : null
12172
13267
  ] })
12173
13268
  ] }),
12174
- dirty ? /* @__PURE__ */ jsx43("span", { id: unsavedChangesId, className: "sr-only", children: "This table view has unsaved changes. Open the view menu to save or update it." }) : null,
12175
- visibleError ? /* @__PURE__ */ jsx43("p", { role: "alert", className: "basis-full break-words text-xs text-destructive", children: visibleError }) : null,
12176
- /* @__PURE__ */ jsx43(Dialog, { open: saveOpen, onOpenChange: setSaveOpen, children: /* @__PURE__ */ jsxs33(DialogContent, { children: [
12177
- /* @__PURE__ */ jsx43(DialogHeader, { children: /* @__PURE__ */ jsx43(DialogTitle, { children: "Save current view" }) }),
12178
- visibleError ? /* @__PURE__ */ jsx43("p", { role: "alert", className: "text-sm text-destructive", children: visibleError }) : null,
12179
- /* @__PURE__ */ jsx43(Input, { "aria-label": "View name", value: name, onChange: (event) => setName(event.target.value), placeholder: "View name", autoFocus: true }),
12180
- /* @__PURE__ */ jsxs33(DialogFooter, { children: [
12181
- /* @__PURE__ */ jsx43(Button, { type: "button", variant: "outline", onClick: () => setSaveOpen(false), children: "Cancel" }),
12182
- /* @__PURE__ */ jsx43(Button, { type: "button", disabled: !name.trim() || saving, onClick: () => void save(), children: saving ? "Saving\u2026" : "Save view" })
13269
+ dirty ? /* @__PURE__ */ jsx44("span", { id: unsavedChangesId, className: "sr-only", children: "This table view has unsaved changes. Open the view menu to save or update it." }) : null,
13270
+ visibleError ? /* @__PURE__ */ jsx44("p", { role: "alert", className: "basis-full break-words text-xs text-destructive", children: visibleError }) : null,
13271
+ /* @__PURE__ */ jsx44(Dialog, { open: saveOpen, onOpenChange: setSaveOpen, children: /* @__PURE__ */ jsxs34(DialogContent, { children: [
13272
+ /* @__PURE__ */ jsx44(DialogHeader, { children: /* @__PURE__ */ jsx44(DialogTitle, { children: "Save current view" }) }),
13273
+ visibleError ? /* @__PURE__ */ jsx44("p", { role: "alert", className: "text-sm text-destructive", children: visibleError }) : null,
13274
+ /* @__PURE__ */ jsx44(Input, { "aria-label": "View name", value: name, onChange: (event) => setName(event.target.value), placeholder: "View name", autoFocus: true }),
13275
+ /* @__PURE__ */ jsxs34(DialogFooter, { children: [
13276
+ /* @__PURE__ */ jsx44(Button, { type: "button", variant: "outline", onClick: () => setSaveOpen(false), children: "Cancel" }),
13277
+ /* @__PURE__ */ jsx44(Button, { type: "button", disabled: !name.trim() || saving, onClick: () => void save(), children: saving ? "Saving\u2026" : "Save view" })
12183
13278
  ] })
12184
13279
  ] }) })
12185
13280
  ] });
@@ -12221,30 +13316,61 @@ function downloadTableAsXlsx({
12221
13316
  URL.revokeObjectURL(url);
12222
13317
  }
12223
13318
  export {
13319
+ BOOLEAN_TRUE_COLOR,
13320
+ CELL_TINT_CLASS,
13321
+ COLOR_RULE_OPS,
13322
+ COLOR_RULE_OP_LABELS,
12224
13323
  DataRowInspector,
12225
13324
  DataRowWindow,
13325
+ EMPTY_TABLE_STYLE,
13326
+ FORMAT_MISMATCH_CLASS,
13327
+ FormattedCell,
12226
13328
  GenericTablePagination,
12227
13329
  MatrxDataTable,
12228
13330
  MatrxDataTableProvider,
12229
13331
  MatrxTableRowAlchemyProvider,
12230
13332
  MatrxUuidCell,
13333
+ NO_FROZEN_COLUMNS,
13334
+ OPS_WITH_VALUE,
13335
+ ROW_TINT_CLASS,
13336
+ STYLE_COLORS,
13337
+ STYLE_COLOR_LABELS,
13338
+ SWATCH_CLASS,
12231
13339
  SavedViewsControl,
13340
+ TABLE_STYLE_METADATA_KEY,
13341
+ TABLE_STYLE_VERSION,
12232
13342
  TableTitleRow,
12233
13343
  TableViewTabs,
13344
+ alignForFormat,
13345
+ applyStylePath,
12234
13346
  buildRowAgentInput,
12235
13347
  buildViewAgentInput,
12236
13348
  buildViewHuman,
12237
13349
  collectSelectOptions,
13350
+ colorForChoice,
12238
13351
  downloadTableAsXlsx,
13352
+ evaluateRule,
12239
13353
  filterKindLabel,
13354
+ formatColumnValue,
13355
+ inferTableSearchRole,
13356
+ isStyleColor,
13357
+ parseTableStyle,
12240
13358
  parseTableViewSnapshot,
13359
+ pixelWidth,
12241
13360
  rankTableSearchRows,
13361
+ resolveCellColor,
12242
13362
  resolveColumnMarker,
12243
13363
  resolveFilterKind,
13364
+ resolveFrozenColumns,
13365
+ resolveRowColor,
13366
+ resolveTableSearchScopes,
12244
13367
  rowsToCsvFromColumns,
12245
13368
  rowsToMarkdownTable,
12246
13369
  rowsToRecordsFromColumns,
12247
13370
  shortUuid,
13371
+ stylePath,
13372
+ tableStyleFromMetadata,
13373
+ tableStyleIsEmpty,
12248
13374
  tableUrlParamPrefix,
12249
13375
  useMatrxDataTableHost,
12250
13376
  useMatrxTableRowAlchemy,