@ai-matrx/design-system 0.21.14 → 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 (37) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/data-table/copy-helpers.d.cts +2 -1
  3. package/dist/data-table/copy-helpers.d.ts +2 -1
  4. package/dist/data-table/filter-engine.d.cts +2 -1
  5. package/dist/data-table/filter-engine.d.ts +2 -1
  6. package/dist/data-table/host.d.cts +2 -1
  7. package/dist/data-table/host.d.ts +2 -1
  8. package/dist/data-table/index.cjs +1525 -398
  9. package/dist/data-table/index.cjs.map +1 -1
  10. package/dist/data-table/index.d.cts +91 -3
  11. package/dist/data-table/index.d.ts +91 -3
  12. package/dist/data-table/index.js +1526 -395
  13. package/dist/data-table/index.js.map +1 -1
  14. package/dist/data-table/infer-filter.d.cts +2 -1
  15. package/dist/data-table/infer-filter.d.ts +2 -1
  16. package/dist/data-table/layered-filters.d.cts +2 -1
  17. package/dist/data-table/layered-filters.d.ts +2 -1
  18. package/dist/data-table/query-control.d.cts +2 -1
  19. package/dist/data-table/query-control.d.ts +2 -1
  20. package/dist/data-table/types.cjs.map +1 -1
  21. package/dist/data-table/types.d.cts +2 -1
  22. package/dist/data-table/types.d.ts +2 -1
  23. package/dist/data-table/url-state.d.cts +2 -1
  24. package/dist/data-table/url-state.d.ts +2 -1
  25. package/dist/data-table/xlsx.d.cts +2 -1
  26. package/dist/data-table/xlsx.d.ts +2 -1
  27. package/dist/field-formats/index.cjs +741 -0
  28. package/dist/field-formats/index.cjs.map +1 -0
  29. package/dist/field-formats/index.d.cts +45 -0
  30. package/dist/field-formats/index.d.ts +45 -0
  31. package/dist/field-formats/index.js +723 -0
  32. package/dist/field-formats/index.js.map +1 -0
  33. package/dist/types-BdbvlF9-.d.cts +204 -0
  34. package/dist/types-BdbvlF9-.d.ts +204 -0
  35. package/dist/{types-emLxze_m.d.ts → types-D-flTpK0.d.ts} +230 -1
  36. package/dist/{types-BgqIKbhq.d.cts → types-Sn249eoy.d.cts} +230 -1
  37. package/package.json +11 -1
@@ -7027,6 +7027,295 @@ function ColumnManagerDragHandle({ id, label }) {
7027
7027
 
7028
7028
  // src/data-table/saved-view-snapshot.ts
7029
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
7030
7319
  var filterSchema = z2.union([
7031
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() }),
7032
7321
  z2.object({ kind: z2.literal("select"), value: z2.string(), values: z2.array(z2.string()).optional(), negated: z2.boolean().optional() }),
@@ -7044,7 +7333,13 @@ var snapshotSchema = z2.object({
7044
7333
  }),
7045
7334
  hidden: z2.array(z2.string().min(1)),
7046
7335
  widths: z2.record(z2.string(), z2.number().finite().positive()).optional()
7047
- })
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()
7048
7343
  });
7049
7344
  function normalizeFilters(raw) {
7050
7345
  const filters = {};
@@ -7061,6 +7356,7 @@ function parseTableViewSnapshot(raw) {
7061
7356
  const parsed = snapshotSchema.safeParse(raw);
7062
7357
  if (!parsed.success) return null;
7063
7358
  const { query, columns } = parsed.data;
7359
+ const style = parsed.data.style === void 0 ? null : parseTableStyle(parsed.data.style);
7064
7360
  return {
7065
7361
  __kind: "matrx-table-view",
7066
7362
  version: 1,
@@ -7078,7 +7374,8 @@ function parseTableViewSnapshot(raw) {
7078
7374
  order: columns.order,
7079
7375
  hidden: columns.hidden,
7080
7376
  ...columns.widths === void 0 ? {} : { widths: columns.widths }
7081
- }
7377
+ },
7378
+ ...style === null || tableStyleIsEmpty(style) ? {} : { style }
7082
7379
  };
7083
7380
  }
7084
7381
 
@@ -7541,8 +7838,740 @@ function defaultRowTitle(row, columns) {
7541
7838
  return value ? isUuidValue(value) ? value.slice(0, 8) : value : "Details";
7542
7839
  }
7543
7840
 
7544
- // 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
7545
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";
7546
8575
  function DirtySavePill({
7547
8576
  changeCount,
7548
8577
  saving,
@@ -7551,20 +8580,20 @@ function DirtySavePill({
7551
8580
  className
7552
8581
  }) {
7553
8582
  if (changeCount <= 0) return null;
7554
- return /* @__PURE__ */ jsx37(
8583
+ return /* @__PURE__ */ jsx38(
7555
8584
  "div",
7556
8585
  {
7557
8586
  className: cn(
7558
8587
  "pointer-events-none fixed inset-x-0 bottom-6 z-50 flex justify-center pb-safe",
7559
8588
  className
7560
8589
  ),
7561
- 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: [
7562
- /* @__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: [
7563
8592
  changeCount,
7564
8593
  " unsaved change",
7565
8594
  changeCount === 1 ? "" : "s"
7566
8595
  ] }),
7567
- /* @__PURE__ */ jsxs27(
8596
+ /* @__PURE__ */ jsxs28(
7568
8597
  Button,
7569
8598
  {
7570
8599
  type: "button",
@@ -7574,12 +8603,12 @@ function DirtySavePill({
7574
8603
  disabled: saving,
7575
8604
  onClick: onCancel,
7576
8605
  children: [
7577
- /* @__PURE__ */ jsx37(X, { className: "h-3.5 w-3.5" }),
8606
+ /* @__PURE__ */ jsx38(X, { className: "h-3.5 w-3.5" }),
7578
8607
  "Cancel"
7579
8608
  ]
7580
8609
  }
7581
8610
  ),
7582
- /* @__PURE__ */ jsxs27(
8611
+ /* @__PURE__ */ jsxs28(
7583
8612
  Button,
7584
8613
  {
7585
8614
  type: "button",
@@ -7588,7 +8617,7 @@ function DirtySavePill({
7588
8617
  disabled: saving,
7589
8618
  onClick: onSave,
7590
8619
  children: [
7591
- 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" }),
7592
8621
  "Save"
7593
8622
  ]
7594
8623
  }
@@ -7600,7 +8629,7 @@ function DirtySavePill({
7600
8629
 
7601
8630
  // src/data-table/EditableTableCell.tsx
7602
8631
  import { useEffect as useEffect14, useRef as useRef12, useState as useState19 } from "react";
7603
- import { jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
8632
+ import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
7604
8633
  function CellEditShell({
7605
8634
  href,
7606
8635
  display,
@@ -7609,8 +8638,8 @@ function CellEditShell({
7609
8638
  editButton
7610
8639
  }) {
7611
8640
  const { Link: HostLink } = useMatrxDataTableHost();
7612
- const Link = HostLink ?? ((props) => /* @__PURE__ */ jsx38("a", { ...props }));
7613
- return /* @__PURE__ */ jsxs28(
8641
+ const Link = HostLink ?? ((props) => /* @__PURE__ */ jsx39("a", { ...props }));
8642
+ return /* @__PURE__ */ jsxs29(
7614
8643
  "span",
7615
8644
  {
7616
8645
  className: cn(
@@ -7622,7 +8651,7 @@ function CellEditShell({
7622
8651
  className
7623
8652
  ),
7624
8653
  children: [
7625
- href ? /* @__PURE__ */ jsx38(
8654
+ href ? /* @__PURE__ */ jsx39(
7626
8655
  Link,
7627
8656
  {
7628
8657
  href,
@@ -7630,7 +8659,7 @@ function CellEditShell({
7630
8659
  className: "min-w-0 flex-1 overflow-hidden truncate rounded outline-none focus-visible:ring-2 focus-visible:ring-ring",
7631
8660
  children: display
7632
8661
  }
7633
- ) : /* @__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 }),
7634
8663
  editButton
7635
8664
  ]
7636
8665
  }
@@ -7655,7 +8684,7 @@ function EditableTableCell({
7655
8684
  }, [editRequest]);
7656
8685
  const usePencil = Boolean(href) || editTrigger === "pencil";
7657
8686
  if (editType === "string") {
7658
- return /* @__PURE__ */ jsx38(
8687
+ return /* @__PURE__ */ jsx39(
7659
8688
  InlineStringEditor,
7660
8689
  {
7661
8690
  value: stringifyCellValue(value),
@@ -7669,30 +8698,30 @@ function EditableTableCell({
7669
8698
  }
7670
8699
  );
7671
8700
  }
7672
- return /* @__PURE__ */ jsxs28(Popover, { open, onOpenChange: setOpen, children: [
7673
- usePencil ? /* @__PURE__ */ jsx38(
8701
+ return /* @__PURE__ */ jsxs29(Popover, { open, onOpenChange: setOpen, children: [
8702
+ usePencil ? /* @__PURE__ */ jsx39(
7674
8703
  CellEditShell,
7675
8704
  {
7676
8705
  ...href === void 0 ? {} : { href },
7677
8706
  display,
7678
8707
  ...dirty === void 0 ? {} : { dirty },
7679
8708
  ...className === void 0 ? {} : { className },
7680
- editButton: /* @__PURE__ */ jsxs28(Tooltip, { children: [
7681
- /* @__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(
7682
8711
  "button",
7683
8712
  {
7684
8713
  type: "button",
7685
8714
  "aria-label": "Edit",
7686
8715
  onClick: (e) => e.stopPropagation(),
7687
8716
  className: CELL_PENCIL_CLASS,
7688
- children: /* @__PURE__ */ jsx38(Pencil, { className: "h-3 w-3" })
8717
+ children: /* @__PURE__ */ jsx39(Pencil, { className: "h-3 w-3" })
7689
8718
  }
7690
8719
  ) }) }),
7691
- /* @__PURE__ */ jsx38(TooltipContent, { children: "Edit" })
8720
+ /* @__PURE__ */ jsx39(TooltipContent, { children: "Edit" })
7692
8721
  ] })
7693
8722
  }
7694
- ) : /* @__PURE__ */ jsxs28(Tooltip, { children: [
7695
- /* @__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(
7696
8725
  "button",
7697
8726
  {
7698
8727
  type: "button",
@@ -7703,20 +8732,20 @@ function EditableTableCell({
7703
8732
  className
7704
8733
  ),
7705
8734
  children: [
7706
- /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 overflow-hidden", children: display }),
7707
- 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
7708
8737
  ]
7709
8738
  }
7710
8739
  ) }) }),
7711
- /* @__PURE__ */ jsx38(TooltipContent, { children: "Edit value" })
8740
+ /* @__PURE__ */ jsx39(TooltipContent, { children: "Edit value" })
7712
8741
  ] }),
7713
- /* @__PURE__ */ jsx38(
8742
+ /* @__PURE__ */ jsx39(
7714
8743
  PopoverContent,
7715
8744
  {
7716
8745
  align: "start",
7717
8746
  className: "w-56 p-2",
7718
8747
  onClick: (e) => e.stopPropagation(),
7719
- children: /* @__PURE__ */ jsx38(
8748
+ children: /* @__PURE__ */ jsx39(
7720
8749
  TypedEditor,
7721
8750
  {
7722
8751
  editType,
@@ -7754,15 +8783,15 @@ function InlineStringEditor({
7754
8783
  }, [editRequest, value]);
7755
8784
  if (!editing) {
7756
8785
  if (usePencil) {
7757
- return /* @__PURE__ */ jsx38(
8786
+ return /* @__PURE__ */ jsx39(
7758
8787
  CellEditShell,
7759
8788
  {
7760
8789
  ...href === void 0 ? {} : { href },
7761
8790
  display,
7762
8791
  ...dirty === void 0 ? {} : { dirty },
7763
8792
  ...className === void 0 ? {} : { className },
7764
- editButton: /* @__PURE__ */ jsxs28(Tooltip, { children: [
7765
- /* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(
8793
+ editButton: /* @__PURE__ */ jsxs29(Tooltip, { children: [
8794
+ /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(
7766
8795
  "button",
7767
8796
  {
7768
8797
  type: "button",
@@ -7773,16 +8802,16 @@ function InlineStringEditor({
7773
8802
  setEditing(true);
7774
8803
  },
7775
8804
  className: CELL_PENCIL_CLASS,
7776
- children: /* @__PURE__ */ jsx38(Pencil, { className: "h-3 w-3" })
8805
+ children: /* @__PURE__ */ jsx39(Pencil, { className: "h-3 w-3" })
7777
8806
  }
7778
8807
  ) }),
7779
- /* @__PURE__ */ jsx38(TooltipContent, { children: "Edit" })
8808
+ /* @__PURE__ */ jsx39(TooltipContent, { children: "Edit" })
7780
8809
  ] })
7781
8810
  }
7782
8811
  );
7783
8812
  }
7784
- return /* @__PURE__ */ jsxs28(Tooltip, { children: [
7785
- /* @__PURE__ */ jsx38(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx38(
8813
+ return /* @__PURE__ */ jsxs29(Tooltip, { children: [
8814
+ /* @__PURE__ */ jsx39(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx39(
7786
8815
  "button",
7787
8816
  {
7788
8817
  type: "button",
@@ -7799,10 +8828,10 @@ function InlineStringEditor({
7799
8828
  children: display
7800
8829
  }
7801
8830
  ) }),
7802
- /* @__PURE__ */ jsx38(TooltipContent, { children: "Click to edit" })
8831
+ /* @__PURE__ */ jsx39(TooltipContent, { children: "Click to edit" })
7803
8832
  ] });
7804
8833
  }
7805
- return /* @__PURE__ */ jsx38(
8834
+ return /* @__PURE__ */ jsx39(
7806
8835
  Input,
7807
8836
  {
7808
8837
  autoFocus: true,
@@ -7838,9 +8867,9 @@ function TypedEditor({
7838
8867
  }) {
7839
8868
  if (editType === "boolean") {
7840
8869
  const checked = Boolean(value);
7841
- return /* @__PURE__ */ jsxs28("div", { className: "flex items-center justify-between gap-2", children: [
7842
- /* @__PURE__ */ jsx38("span", { className: "text-xs font-medium", children: "Value" }),
7843
- /* @__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(
7844
8873
  Checkbox,
7845
8874
  {
7846
8875
  checked,
@@ -7850,7 +8879,7 @@ function TypedEditor({
7850
8879
  ] });
7851
8880
  }
7852
8881
  if (editType === "number") {
7853
- return /* @__PURE__ */ jsx38(
8882
+ return /* @__PURE__ */ jsx39(
7854
8883
  NumberEditor,
7855
8884
  {
7856
8885
  value: typeof value === "number" ? value : Number(value) || 0,
@@ -7860,7 +8889,7 @@ function TypedEditor({
7860
8889
  );
7861
8890
  }
7862
8891
  if (editType === "tags") {
7863
- return /* @__PURE__ */ jsx38(
8892
+ return /* @__PURE__ */ jsx39(
7864
8893
  TagsEditor,
7865
8894
  {
7866
8895
  value: Array.isArray(value) ? value.map(String) : [],
@@ -7871,19 +8900,19 @@ function TypedEditor({
7871
8900
  );
7872
8901
  }
7873
8902
  if (editType === "select") {
7874
- return /* @__PURE__ */ jsxs28(
8903
+ return /* @__PURE__ */ jsxs29(
7875
8904
  Select,
7876
8905
  {
7877
8906
  value: stringifyCellValue(value),
7878
8907
  onValueChange: (v) => onCommit(v),
7879
8908
  children: [
7880
- /* @__PURE__ */ jsx38(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx38(SelectValue, {}) }),
7881
- /* @__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)) })
7882
8911
  ]
7883
8912
  }
7884
8913
  );
7885
8914
  }
7886
- return /* @__PURE__ */ jsx38(
8915
+ return /* @__PURE__ */ jsx39(
7887
8916
  Input,
7888
8917
  {
7889
8918
  type: "date",
@@ -7913,11 +8942,11 @@ function TagsEditor({
7913
8942
  const matches = suggestions.filter(
7914
8943
  (s) => !tags.includes(s.value) && s.value !== "__none__" && (!draft || s.label.toLowerCase().includes(draft.trim().toLowerCase()))
7915
8944
  ).slice(0, 6);
7916
- return /* @__PURE__ */ jsxs28("div", { className: "space-y-2", onClick: (e) => e.stopPropagation(), children: [
7917
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-wrap gap-1", children: [
7918
- tags.length === 0 && /* @__PURE__ */ jsx38("span", { className: "text-xs text-muted-foreground", children: "No tags" }),
7919
- tags.map((tag) => /* @__PURE__ */ jsxs28(Tooltip, { children: [
7920
- /* @__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(
7921
8950
  "button",
7922
8951
  {
7923
8952
  type: "button",
@@ -7926,17 +8955,17 @@ function TagsEditor({
7926
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",
7927
8956
  children: [
7928
8957
  tag,
7929
- /* @__PURE__ */ jsx38(X, { className: "h-2.5 w-2.5" })
8958
+ /* @__PURE__ */ jsx39(X, { className: "h-2.5 w-2.5" })
7930
8959
  ]
7931
8960
  }
7932
8961
  ) }),
7933
- /* @__PURE__ */ jsxs28(TooltipContent, { children: [
8962
+ /* @__PURE__ */ jsxs29(TooltipContent, { children: [
7934
8963
  "Remove ",
7935
8964
  tag
7936
8965
  ] })
7937
8966
  ] }, tag))
7938
8967
  ] }),
7939
- /* @__PURE__ */ jsx38(
8968
+ /* @__PURE__ */ jsx39(
7940
8969
  Input,
7941
8970
  {
7942
8971
  autoFocus: true,
@@ -7957,7 +8986,7 @@ function TagsEditor({
7957
8986
  className: "h-8 text-xs"
7958
8987
  }
7959
8988
  ),
7960
- 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(
7961
8990
  "button",
7962
8991
  {
7963
8992
  type: "button",
@@ -7970,8 +8999,8 @@ function TagsEditor({
7970
8999
  },
7971
9000
  s.value
7972
9001
  )) }),
7973
- /* @__PURE__ */ jsxs28("div", { className: "flex justify-end gap-1 pt-1", children: [
7974
- /* @__PURE__ */ jsx38(
9002
+ /* @__PURE__ */ jsxs29("div", { className: "flex justify-end gap-1 pt-1", children: [
9003
+ /* @__PURE__ */ jsx39(
7975
9004
  Button,
7976
9005
  {
7977
9006
  size: "sm",
@@ -7979,17 +9008,17 @@ function TagsEditor({
7979
9008
  className: "h-7 px-2",
7980
9009
  "aria-label": "Cancel edit",
7981
9010
  onClick: onCancel,
7982
- children: /* @__PURE__ */ jsx38(X, { className: "h-3.5 w-3.5" })
9011
+ children: /* @__PURE__ */ jsx39(X, { className: "h-3.5 w-3.5" })
7983
9012
  }
7984
9013
  ),
7985
- /* @__PURE__ */ jsx38(
9014
+ /* @__PURE__ */ jsx39(
7986
9015
  Button,
7987
9016
  {
7988
9017
  size: "sm",
7989
9018
  className: "h-7 px-2",
7990
9019
  "aria-label": "Apply tags",
7991
9020
  onClick: () => onCommit(tags),
7992
- children: /* @__PURE__ */ jsx38(Check, { className: "h-3.5 w-3.5" })
9021
+ children: /* @__PURE__ */ jsx39(Check, { className: "h-3.5 w-3.5" })
7993
9022
  }
7994
9023
  )
7995
9024
  ] })
@@ -8001,8 +9030,8 @@ function NumberEditor({
8001
9030
  onCancel
8002
9031
  }) {
8003
9032
  const [draft, setDraft] = useState19(String(value));
8004
- return /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-2", children: [
8005
- /* @__PURE__ */ jsx38(
9033
+ return /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-2", children: [
9034
+ /* @__PURE__ */ jsx39(
8006
9035
  Input,
8007
9036
  {
8008
9037
  autoFocus: true,
@@ -8019,8 +9048,8 @@ function NumberEditor({
8019
9048
  }
8020
9049
  }
8021
9050
  ),
8022
- /* @__PURE__ */ jsxs28("div", { className: "flex justify-end gap-1", children: [
8023
- /* @__PURE__ */ jsx38(
9051
+ /* @__PURE__ */ jsxs29("div", { className: "flex justify-end gap-1", children: [
9052
+ /* @__PURE__ */ jsx39(
8024
9053
  Button,
8025
9054
  {
8026
9055
  type: "button",
@@ -8029,10 +9058,10 @@ function NumberEditor({
8029
9058
  className: "h-7",
8030
9059
  "aria-label": "Cancel edit",
8031
9060
  onClick: onCancel,
8032
- children: /* @__PURE__ */ jsx38(X, { className: "h-3.5 w-3.5" })
9061
+ children: /* @__PURE__ */ jsx39(X, { className: "h-3.5 w-3.5" })
8033
9062
  }
8034
9063
  ),
8035
- /* @__PURE__ */ jsx38(
9064
+ /* @__PURE__ */ jsx39(
8036
9065
  Button,
8037
9066
  {
8038
9067
  type: "button",
@@ -8043,7 +9072,7 @@ function NumberEditor({
8043
9072
  const n = Number(draft);
8044
9073
  if (Number.isFinite(n)) onCommit(n);
8045
9074
  },
8046
- children: /* @__PURE__ */ jsx38(Check, { className: "h-3.5 w-3.5" })
9075
+ children: /* @__PURE__ */ jsx39(Check, { className: "h-3.5 w-3.5" })
8047
9076
  }
8048
9077
  )
8049
9078
  ] })
@@ -8051,24 +9080,24 @@ function NumberEditor({
8051
9080
  }
8052
9081
 
8053
9082
  // src/data-table/ToolbarFacets.tsx
8054
- import { jsx as jsx39, jsxs as jsxs29 } from "react/jsx-runtime";
9083
+ import { jsx as jsx40, jsxs as jsxs30 } from "react/jsx-runtime";
8055
9084
  function ToolbarFacets({ facets }) {
8056
9085
  if (facets.length === 0) return null;
8057
- 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) => {
8058
9087
  if (facet.type === "custom") {
8059
- return /* @__PURE__ */ jsx39("div", { children: facet.render() }, facet.id);
9088
+ return /* @__PURE__ */ jsx40("div", { children: facet.render() }, facet.id);
8060
9089
  }
8061
9090
  const defaultValue = facet.defaultValue ?? facet.options[0]?.value ?? "";
8062
9091
  const isNonDefault = facet.value !== defaultValue;
8063
- return /* @__PURE__ */ jsxs29(
9092
+ return /* @__PURE__ */ jsxs30(
8064
9093
  "div",
8065
9094
  {
8066
9095
  className: "flex flex-wrap items-center gap-1.5 max-sm:grid max-sm:w-full max-sm:grid-cols-3",
8067
9096
  children: [
8068
- 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,
8069
9098
  facet.options.map((opt) => {
8070
9099
  const active = facet.value === opt.value;
8071
- return /* @__PURE__ */ jsxs29(
9100
+ return /* @__PURE__ */ jsxs30(
8072
9101
  Button,
8073
9102
  {
8074
9103
  type: "button",
@@ -8082,8 +9111,8 @@ function ToolbarFacets({ facets }) {
8082
9111
  children: [
8083
9112
  opt.icon,
8084
9113
  opt.label,
8085
- active && isNonDefault ? /* @__PURE__ */ jsx39(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs29(Tooltip, { children: [
8086
- /* @__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(
8087
9116
  "span",
8088
9117
  {
8089
9118
  role: "button",
@@ -8101,10 +9130,10 @@ function ToolbarFacets({ facets }) {
8101
9130
  facet.onChange(defaultValue);
8102
9131
  }
8103
9132
  },
8104
- children: /* @__PURE__ */ jsx39(X, { className: "h-3 w-3" })
9133
+ children: /* @__PURE__ */ jsx40(X, { className: "h-3 w-3" })
8105
9134
  }
8106
9135
  ) }),
8107
- /* @__PURE__ */ jsx39(TooltipContent, { side: "top", children: "Clear this filter" })
9136
+ /* @__PURE__ */ jsx40(TooltipContent, { side: "top", children: "Clear this filter" })
8108
9137
  ] }) }) : null
8109
9138
  ]
8110
9139
  },
@@ -8131,7 +9160,7 @@ function resetToolbarFacets(facets) {
8131
9160
 
8132
9161
  // src/data-table/LayeredFilterBuilder.tsx
8133
9162
  import { useState as useState20 } from "react";
8134
- 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";
8135
9164
  function moveRule(rules, from, to) {
8136
9165
  if (from === to || to < 0 || to >= rules.length) return [...rules];
8137
9166
  const next = [...rules];
@@ -8177,8 +9206,8 @@ function LayeredFilterBuilder({
8177
9206
  const reorder = (from, to) => {
8178
9207
  onChange(moveRule(rules, from, to));
8179
9208
  };
8180
- return /* @__PURE__ */ jsxs30("div", { className: "flex min-w-0 flex-wrap items-center gap-1", children: [
8181
- /* @__PURE__ */ jsxs30(
9209
+ return /* @__PURE__ */ jsxs31("div", { className: "flex min-w-0 flex-wrap items-center gap-1", children: [
9210
+ /* @__PURE__ */ jsxs31(
8182
9211
  Popover,
8183
9212
  {
8184
9213
  open,
@@ -8190,7 +9219,7 @@ function LayeredFilterBuilder({
8190
9219
  }
8191
9220
  },
8192
9221
  children: [
8193
- /* @__PURE__ */ jsx40(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs30(
9222
+ /* @__PURE__ */ jsx41(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs31(
8194
9223
  Button,
8195
9224
  {
8196
9225
  type: "button",
@@ -8199,25 +9228,25 @@ function LayeredFilterBuilder({
8199
9228
  className: "h-8 gap-1.5 px-2 text-xs",
8200
9229
  "aria-label": label,
8201
9230
  children: [
8202
- /* @__PURE__ */ jsx40(SlidersHorizontal, { className: "h-3.5 w-3.5" }),
8203
- /* @__PURE__ */ jsx40("span", { className: "hidden sm:inline", children: rules.length > 0 ? `${rules.length} layers` : "Advanced" }),
8204
- 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
8205
9234
  ]
8206
9235
  }
8207
9236
  ) }),
8208
- /* @__PURE__ */ jsxs30(
9237
+ /* @__PURE__ */ jsxs31(
8209
9238
  PopoverContent,
8210
9239
  {
8211
9240
  align: "start",
8212
9241
  sideOffset: 6,
8213
9242
  className: "w-[min(46rem,calc(100vw-1rem))] p-0",
8214
9243
  children: [
8215
- /* @__PURE__ */ jsxs30("div", { className: "flex items-start justify-between gap-3 border-b border-border px-3 py-2.5", children: [
8216
- /* @__PURE__ */ jsxs30("div", { children: [
8217
- /* @__PURE__ */ jsx40("p", { className: "text-sm font-semibold text-foreground", children: "Narrow these results" }),
8218
- /* @__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." })
8219
9248
  ] }),
8220
- rules.length > 0 ? /* @__PURE__ */ jsx40(
9249
+ rules.length > 0 ? /* @__PURE__ */ jsx41(
8221
9250
  Button,
8222
9251
  {
8223
9252
  type: "button",
@@ -8229,10 +9258,10 @@ function LayeredFilterBuilder({
8229
9258
  }
8230
9259
  ) : null
8231
9260
  ] }),
8232
- /* @__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: [
8233
- /* @__PURE__ */ jsx40("p", { className: "text-sm font-medium text-foreground", children: "Start with one simple layer" }),
8234
- /* @__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." })
8235
- ] }) : 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(
8236
9265
  LayeredRuleRow,
8237
9266
  {
8238
9267
  index,
@@ -8252,9 +9281,9 @@ function LayeredFilterBuilder({
8252
9281
  },
8253
9282
  rule.id
8254
9283
  )) }),
8255
- /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between gap-2 border-t border-border px-3 py-2", children: [
8256
- /* @__PURE__ */ jsx40("p", { className: "text-[11px] text-muted-foreground", children: "The regular search still works and is applied before these layers." }),
8257
- /* @__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(
8258
9287
  Button,
8259
9288
  {
8260
9289
  type: "button",
@@ -8264,7 +9293,7 @@ function LayeredFilterBuilder({
8264
9293
  disabled: rules.length >= maxRules,
8265
9294
  onClick: addRule,
8266
9295
  children: [
8267
- /* @__PURE__ */ jsx40(Plus, { className: "h-3.5 w-3.5" }),
9296
+ /* @__PURE__ */ jsx41(Plus, { className: "h-3.5 w-3.5" }),
8268
9297
  " Add layer"
8269
9298
  ]
8270
9299
  }
@@ -8276,7 +9305,7 @@ function LayeredFilterBuilder({
8276
9305
  ]
8277
9306
  }
8278
9307
  ),
8279
- rules.map((rule, index) => /* @__PURE__ */ jsxs30(
9308
+ rules.map((rule, index) => /* @__PURE__ */ jsxs31(
8280
9309
  "span",
8281
9310
  {
8282
9311
  className: cn(
@@ -8284,7 +9313,7 @@ function LayeredFilterBuilder({
8284
9313
  isCompleteLayeredFilterRule(rule) ? "border-border bg-muted/50 text-foreground" : "border-dashed border-warning/50 bg-warning/10 text-warning"
8285
9314
  ),
8286
9315
  children: [
8287
- /* @__PURE__ */ jsxs30(
9316
+ /* @__PURE__ */ jsxs31(
8288
9317
  "button",
8289
9318
  {
8290
9319
  type: "button",
@@ -8292,19 +9321,19 @@ function LayeredFilterBuilder({
8292
9321
  onClick: () => setOpen(true),
8293
9322
  title: isCompleteLayeredFilterRule(rule) ? layeredFilterRuleSummary(rule, fields) : `Layer ${index + 1} needs a value`,
8294
9323
  children: [
8295
- /* @__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 }),
8296
9325
  isCompleteLayeredFilterRule(rule) ? layeredFilterRuleSummary(rule, fields) : "Choose a value"
8297
9326
  ]
8298
9327
  }
8299
9328
  ),
8300
- /* @__PURE__ */ jsx40(
9329
+ /* @__PURE__ */ jsx41(
8301
9330
  "button",
8302
9331
  {
8303
9332
  type: "button",
8304
9333
  className: "shrink-0 rounded-full p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
8305
9334
  "aria-label": `Remove filter layer ${index + 1}`,
8306
9335
  onClick: () => removeRule(index),
8307
- children: /* @__PURE__ */ jsx40(X, { className: "h-3 w-3" })
9336
+ children: /* @__PURE__ */ jsx41(X, { className: "h-3 w-3" })
8308
9337
  }
8309
9338
  )
8310
9339
  ]
@@ -8334,7 +9363,7 @@ function LayeredRuleRow({
8334
9363
  event.preventDefault();
8335
9364
  onKeyboardMove(event.key === "ArrowUp" ? -1 : 1);
8336
9365
  };
8337
- return /* @__PURE__ */ jsxs30(
9366
+ return /* @__PURE__ */ jsxs31(
8338
9367
  "div",
8339
9368
  {
8340
9369
  className: cn(
@@ -8347,7 +9376,7 @@ function LayeredRuleRow({
8347
9376
  onDrop(index);
8348
9377
  },
8349
9378
  children: [
8350
- /* @__PURE__ */ jsx40(
9379
+ /* @__PURE__ */ jsx41(
8351
9380
  "button",
8352
9381
  {
8353
9382
  type: "button",
@@ -8361,10 +9390,10 @@ function LayeredRuleRow({
8361
9390
  },
8362
9391
  onDragEnd,
8363
9392
  onKeyDown: handleMoveKey,
8364
- children: /* @__PURE__ */ jsx40(GripVertical, { className: "h-3.5 w-3.5" })
9393
+ children: /* @__PURE__ */ jsx41(GripVertical, { className: "h-3.5 w-3.5" })
8365
9394
  }
8366
9395
  ),
8367
- /* @__PURE__ */ jsxs30(
9396
+ /* @__PURE__ */ jsxs31(
8368
9397
  Select,
8369
9398
  {
8370
9399
  value: field.id,
@@ -8382,16 +9411,16 @@ function LayeredRuleRow({
8382
9411
  });
8383
9412
  },
8384
9413
  children: [
8385
- /* @__PURE__ */ jsx40(
9414
+ /* @__PURE__ */ jsx41(
8386
9415
  SelectTrigger,
8387
9416
  {
8388
9417
  size: "sm",
8389
9418
  className: "h-7 w-full text-xs max-sm:col-span-1",
8390
9419
  "aria-label": `Filter layer ${index + 1} field`,
8391
- children: /* @__PURE__ */ jsx40(SelectValue, {})
9420
+ children: /* @__PURE__ */ jsx41(SelectValue, {})
8392
9421
  }
8393
9422
  ),
8394
- /* @__PURE__ */ jsx40(SelectContent, { children: fields.map((candidate) => /* @__PURE__ */ jsx40(
9423
+ /* @__PURE__ */ jsx41(SelectContent, { children: fields.map((candidate) => /* @__PURE__ */ jsx41(
8395
9424
  SelectItem,
8396
9425
  {
8397
9426
  value: candidate.id,
@@ -8403,7 +9432,7 @@ function LayeredRuleRow({
8403
9432
  ]
8404
9433
  }
8405
9434
  ),
8406
- /* @__PURE__ */ jsxs30(
9435
+ /* @__PURE__ */ jsxs31(
8407
9436
  Select,
8408
9437
  {
8409
9438
  value: rule.operator,
@@ -8415,35 +9444,35 @@ function LayeredRuleRow({
8415
9444
  });
8416
9445
  },
8417
9446
  children: [
8418
- /* @__PURE__ */ jsx40(
9447
+ /* @__PURE__ */ jsx41(
8419
9448
  SelectTrigger,
8420
9449
  {
8421
9450
  size: "sm",
8422
9451
  className: "h-7 w-full text-xs max-sm:col-start-2",
8423
9452
  "aria-label": `Filter layer ${index + 1} operator`,
8424
- children: /* @__PURE__ */ jsx40(SelectValue, {})
9453
+ children: /* @__PURE__ */ jsx41(SelectValue, {})
8425
9454
  }
8426
9455
  ),
8427
- /* @__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)) })
8428
9457
  ]
8429
9458
  }
8430
9459
  ),
8431
- /* @__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(
8432
9461
  Select,
8433
9462
  {
8434
9463
  value: rule.value,
8435
9464
  onValueChange: (value) => onChange({ value }),
8436
9465
  children: [
8437
- /* @__PURE__ */ jsx40(
9466
+ /* @__PURE__ */ jsx41(
8438
9467
  SelectTrigger,
8439
9468
  {
8440
9469
  size: "sm",
8441
9470
  className: "h-7 w-full text-xs",
8442
9471
  "aria-label": `Filter layer ${index + 1} value`,
8443
- children: /* @__PURE__ */ jsx40(SelectValue, {})
9472
+ children: /* @__PURE__ */ jsx41(SelectValue, {})
8444
9473
  }
8445
9474
  ),
8446
- /* @__PURE__ */ jsx40(SelectContent, { children: field.options.map((option) => /* @__PURE__ */ jsx40(
9475
+ /* @__PURE__ */ jsx41(SelectContent, { children: field.options.map((option) => /* @__PURE__ */ jsx41(
8447
9476
  SelectItem,
8448
9477
  {
8449
9478
  value: option.value,
@@ -8454,8 +9483,8 @@ function LayeredRuleRow({
8454
9483
  )) })
8455
9484
  ]
8456
9485
  }
8457
- ) : /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-1", children: [
8458
- /* @__PURE__ */ jsx40(
9486
+ ) : /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-1", children: [
9487
+ /* @__PURE__ */ jsx41(
8459
9488
  Input,
8460
9489
  {
8461
9490
  value: rule.value,
@@ -8466,9 +9495,9 @@ function LayeredRuleRow({
8466
9495
  "aria-label": `Filter layer ${index + 1} value`
8467
9496
  }
8468
9497
  ),
8469
- rule.operator === "between" ? /* @__PURE__ */ jsxs30(Fragment5, { children: [
8470
- /* @__PURE__ */ jsx40("span", { className: "text-[11px] text-muted-foreground", children: "and" }),
8471
- /* @__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(
8472
9501
  Input,
8473
9502
  {
8474
9503
  value: rule.valueTo ?? "",
@@ -8481,7 +9510,7 @@ function LayeredRuleRow({
8481
9510
  )
8482
9511
  ] }) : null
8483
9512
  ] }) }),
8484
- /* @__PURE__ */ jsx40(
9513
+ /* @__PURE__ */ jsx41(
8485
9514
  Button,
8486
9515
  {
8487
9516
  type: "button",
@@ -8490,7 +9519,7 @@ function LayeredRuleRow({
8490
9519
  className: "h-7 w-7 p-0 text-muted-foreground hover:text-destructive max-sm:col-start-3 max-sm:row-start-1",
8491
9520
  "aria-label": `Remove filter layer ${index + 1}`,
8492
9521
  onClick: onRemove,
8493
- children: /* @__PURE__ */ jsx40(Trash2, { className: "h-3.5 w-3.5" })
9522
+ children: /* @__PURE__ */ jsx41(Trash2, { className: "h-3.5 w-3.5" })
8494
9523
  }
8495
9524
  )
8496
9525
  ]
@@ -8603,7 +9632,7 @@ function safeQueryPage(requestedPage, totalItems, pageSize) {
8603
9632
  }
8604
9633
 
8605
9634
  // src/data-table/MatrxDataTable.tsx
8606
- 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";
8607
9636
  function TableToolbarAction({
8608
9637
  HostAction,
8609
9638
  ariaLabel,
@@ -8614,10 +9643,10 @@ function TableToolbarAction({
8614
9643
  children
8615
9644
  }) {
8616
9645
  if (HostAction) {
8617
- 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 }) });
8618
9647
  }
8619
- return /* @__PURE__ */ jsxs31(Tooltip, { children: [
8620
- /* @__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(
8621
9650
  Button,
8622
9651
  {
8623
9652
  type: "button",
@@ -8632,7 +9661,7 @@ function TableToolbarAction({
8632
9661
  children: isValidElement2(children) ? cloneElement2(children, { className: cn("h-5 w-5", children.props.className) }) : children
8633
9662
  }
8634
9663
  ) }) }),
8635
- /* @__PURE__ */ jsx41(TooltipContent, { children: tooltip ?? ariaLabel })
9664
+ /* @__PURE__ */ jsx42(TooltipContent, { children: tooltip ?? ariaLabel })
8636
9665
  ] });
8637
9666
  }
8638
9667
  function hasSameRowReferences(previous, next) {
@@ -8649,7 +9678,7 @@ function TableRowCopyControl({
8649
9678
  sourceId,
8650
9679
  defaultColumns
8651
9680
  }) {
8652
- return /* @__PURE__ */ jsx41(CopyButtons, { size, ...tableRowCopyProps(copy, row, sourceId, defaultColumns) });
9681
+ return /* @__PURE__ */ jsx42(CopyButtons, { size, ...tableRowCopyProps(copy, row, sourceId, defaultColumns) });
8653
9682
  }
8654
9683
  function tableRowCopyProps(copy, row, sourceId, defaultColumns) {
8655
9684
  const aiVariants = copy.rowAiVariants?.(row);
@@ -8673,8 +9702,8 @@ function isStringArray(value) {
8673
9702
  }
8674
9703
  var activeUrlTableIds = /* @__PURE__ */ new Set();
8675
9704
  function MatrxDataTable(props) {
8676
- if (!props.urlState) return /* @__PURE__ */ jsx41(MatrxDataTableCore, { ...props });
8677
- 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 });
8678
9707
  }
8679
9708
  function MatrxDataTableWithUrlState({
8680
9709
  urlState,
@@ -8729,7 +9758,7 @@ function MatrxDataTableWithUrlState({
8729
9758
  props.selection?.onSelectedIdsChange(ids);
8730
9759
  }
8731
9760
  } : props.selection;
8732
- return /* @__PURE__ */ jsx41(
9761
+ return /* @__PURE__ */ jsx42(
8733
9762
  MatrxDataTableCore,
8734
9763
  {
8735
9764
  ...props,
@@ -8781,7 +9810,7 @@ function opensRowHref(event) {
8781
9810
  return event.metaKey || event.ctrlKey || event.shiftKey || event.button === 1;
8782
9811
  }
8783
9812
  function TableContextPassthrough({ children }) {
8784
- return /* @__PURE__ */ jsx41(Fragment7, { children });
9813
+ return /* @__PURE__ */ jsx42(Fragment7, { children });
8785
9814
  }
8786
9815
  function MatrxDataTableCore({
8787
9816
  data: suppliedData,
@@ -8822,6 +9851,8 @@ function MatrxDataTableCore({
8822
9851
  rowActions,
8823
9852
  footerRows = [],
8824
9853
  rowClassName,
9854
+ cellClassName,
9855
+ tableStyle,
8825
9856
  highlightedIndex,
8826
9857
  onViewChange,
8827
9858
  rowWrapper,
@@ -9419,6 +10450,48 @@ function MatrxDataTableCore({
9419
10450
  setFixedTableGeometry(geometry);
9420
10451
  }, [resolvedDensity, measureFixedTableGeometry, usesMeasuredFixedLayout]);
9421
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
+ };
9422
10495
  const declaredVisibleCopyColumns = useMemo7(
9423
10496
  () => visibleColumns.filter((column) => column.accessorFn !== void 0 || column.accessorKey !== void 0),
9424
10497
  [visibleColumns]
@@ -9626,9 +10699,9 @@ function MatrxDataTableCore({
9626
10699
  const showToolbarCopy = effectiveCopy !== void 0 && effectiveCopy.showToolbar !== false;
9627
10700
  const renderRowActions = (row, controls) => {
9628
10701
  const actions = rowActions?.(row, controls);
9629
- const scopedActions = /* @__PURE__ */ jsx41(MatrxTableRowControlsScope, { value: controls, children: actions });
10702
+ const scopedActions = /* @__PURE__ */ jsx42(MatrxTableRowControlsScope, { value: controls, children: actions });
9630
10703
  if (!effectiveCopy || !showRowCopy) return scopedActions;
9631
- return /* @__PURE__ */ jsx41(
10704
+ return /* @__PURE__ */ jsx42(
9632
10705
  MatrxTableRowAlchemyProvider,
9633
10706
  {
9634
10707
  copy: tableRowCopyProps(effectiveCopy, row, `${tableCopySourceNamespace}:row:${getRowId(row)}`, copy === void 0 ? declaredVisibleCopyColumns : void 0),
@@ -9725,7 +10798,7 @@ function MatrxDataTableCore({
9725
10798
  const renderedEmptyState = remoteQuery === null && data.length > 0 && hasActiveFilters ? {
9726
10799
  title: "No matching rows",
9727
10800
  description: "No rows match the current search or filters.",
9728
- 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" }),
9729
10802
  icon: void 0
9730
10803
  } : emptyState;
9731
10804
  const commitCell = (rowId, field, next) => {
@@ -10097,7 +11170,7 @@ function MatrxDataTableCore({
10097
11170
  const display = renderCell(applyRowEdits(row, rowEdits), col, index);
10098
11171
  const href = col.href?.(row) ?? void 0;
10099
11172
  if (editEnabled && col.editable && (col.editableIf?.(row) ?? true)) {
10100
- return /* @__PURE__ */ jsx41(
11173
+ return /* @__PURE__ */ jsx42(
10101
11174
  EditableTableCell,
10102
11175
  {
10103
11176
  value: rowEdits && field in rowEdits ? rowEdits[field] : getCellValue(row, col),
@@ -10112,7 +11185,7 @@ function MatrxDataTableCore({
10112
11185
  }
10113
11186
  );
10114
11187
  }
10115
- 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;
10116
11189
  };
10117
11190
  const currentViewSnapshot = useMemo7(
10118
11191
  () => ({
@@ -10218,7 +11291,7 @@ function MatrxDataTableCore({
10218
11291
  },
10219
11292
  [columns, commitColumnState, commitColumnWidths, controlledQuery, intelligentSearchEnabled, intelligentSearchScopes, toolbar]
10220
11293
  );
10221
- 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(
10222
11295
  DndContext,
10223
11296
  {
10224
11297
  id: tableDndContextId,
@@ -10311,7 +11384,7 @@ function MatrxDataTableCore({
10311
11384
  commitColumnState(order, effectiveHiddenColumnIds);
10312
11385
  },
10313
11386
  children: [
10314
- /* @__PURE__ */ jsxs31(
11387
+ /* @__PURE__ */ jsxs32(
10315
11388
  "div",
10316
11389
  {
10317
11390
  ref: rootRef,
@@ -10326,14 +11399,14 @@ function MatrxDataTableCore({
10326
11399
  ),
10327
11400
  children: [
10328
11401
  notice,
10329
- savedViewError ? /* @__PURE__ */ jsx41("p", { role: "alert", className: "shrink-0 text-xs text-destructive", children: savedViewError }) : null,
10330
- toolbarActionError ? /* @__PURE__ */ jsx41("p", { role: "alert", className: "shrink-0 text-xs text-destructive", children: toolbarActionError }) : null,
10331
- !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(
10332
11405
  TableTitleRow,
10333
11406
  {
10334
- 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,
10335
11408
  ...toolbar?.title === void 0 ? {} : { title: toolbar.title },
10336
- 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(
10337
11410
  SavedViews,
10338
11411
  {
10339
11412
  tableId,
@@ -10342,7 +11415,7 @@ function MatrxDataTableCore({
10342
11415
  onApply: applySavedView
10343
11416
  }
10344
11417
  ) }) : void 0,
10345
- search: showSearch ? intelligentSearchEnabled ? /* @__PURE__ */ jsx41(
11418
+ search: showSearch ? intelligentSearchEnabled ? /* @__PURE__ */ jsx42(
10346
11419
  TableSearch,
10347
11420
  {
10348
11421
  value: searchValue,
@@ -10352,7 +11425,7 @@ function MatrxDataTableCore({
10352
11425
  scopes: intelligentSearchScopes,
10353
11426
  ...toolbar?.searchPlaceholder === void 0 ? {} : { placeholder: toolbar.searchPlaceholder }
10354
11427
  }
10355
- ) : /* @__PURE__ */ jsxs31(
11428
+ ) : /* @__PURE__ */ jsxs32(
10356
11429
  "div",
10357
11430
  {
10358
11431
  "data-matrx-table-search": true,
@@ -10361,9 +11434,9 @@ function MatrxDataTableCore({
10361
11434
  toolbar?.searchMatch ? "sm:max-w-md" : "sm:max-w-xs"
10362
11435
  ),
10363
11436
  children: [
10364
- /* @__PURE__ */ jsxs31("div", { className: "relative min-w-0 flex-1", children: [
10365
- /* @__PURE__ */ jsx41(Search, { className: "absolute left-2 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" }),
10366
- /* @__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(
10367
11440
  Input,
10368
11441
  {
10369
11442
  value: searchValue,
@@ -10376,22 +11449,22 @@ function MatrxDataTableCore({
10376
11449
  style: { fontSize: "16px" }
10377
11450
  }
10378
11451
  ),
10379
- searchValue ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
10380
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
11452
+ searchValue ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
11453
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
10381
11454
  "button",
10382
11455
  {
10383
11456
  type: "button",
10384
11457
  "aria-label": "Clear search",
10385
11458
  className: "absolute right-1.5 top-1/2 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground",
10386
11459
  onClick: () => setSearchValue(""),
10387
- children: /* @__PURE__ */ jsx41(X, { className: "h-5 w-5" })
11460
+ children: /* @__PURE__ */ jsx42(X, { className: "h-5 w-5" })
10388
11461
  }
10389
11462
  ) }),
10390
- /* @__PURE__ */ jsx41(TooltipContent, { children: "Clear search" })
11463
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "Clear search" })
10391
11464
  ] }) : null
10392
11465
  ] }),
10393
- toolbar?.searchMatch ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
10394
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs31(
11466
+ toolbar?.searchMatch ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
11467
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs32(
10395
11468
  Button,
10396
11469
  {
10397
11470
  type: "button",
@@ -10404,18 +11477,18 @@ function MatrxDataTableCore({
10404
11477
  searchMatchMode === "whole_words" ? "contains" : "whole_words"
10405
11478
  ),
10406
11479
  children: [
10407
- /* @__PURE__ */ jsx41(WholeWord, { className: "h-5 w-5" }),
11480
+ /* @__PURE__ */ jsx42(WholeWord, { className: "h-5 w-5" }),
10408
11481
  searchMatchMode === "whole_words" ? "Whole words" : "Contains"
10409
11482
  ]
10410
11483
  }
10411
11484
  ) }),
10412
- /* @__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" })
10413
11486
  ] }) : null
10414
11487
  ]
10415
11488
  }
10416
11489
  ) : null,
10417
11490
  children: [
10418
- toolbar?.layeredFilters ? /* @__PURE__ */ jsx41(
11491
+ toolbar?.layeredFilters ? /* @__PURE__ */ jsx42(
10419
11492
  LayeredFilterBuilder,
10420
11493
  {
10421
11494
  fields: toolbar.layeredFilters.fields,
@@ -10425,9 +11498,9 @@ function MatrxDataTableCore({
10425
11498
  label: toolbar.layeredFilters.label
10426
11499
  }
10427
11500
  ) : null,
10428
- toolbar?.anyOf ? /* @__PURE__ */ jsxs31("div", { className: "relative w-full max-w-xs", children: [
10429
- /* @__PURE__ */ jsx41(Search, { className: "absolute left-2 top-1/2 h-5 w-5 -translate-y-1/2 text-muted-foreground" }),
10430
- /* @__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(
10431
11504
  Input,
10432
11505
  {
10433
11506
  value: anyOfValue,
@@ -10437,22 +11510,22 @@ function MatrxDataTableCore({
10437
11510
  style: { fontSize: "16px" }
10438
11511
  }
10439
11512
  ),
10440
- anyOfValue ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
10441
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
11513
+ anyOfValue ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
11514
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
10442
11515
  "button",
10443
11516
  {
10444
11517
  type: "button",
10445
11518
  "aria-label": "Clear match-any search",
10446
11519
  className: "absolute right-1.5 top-1/2 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground",
10447
11520
  onClick: () => setAnyOfValue(""),
10448
- children: /* @__PURE__ */ jsx41(X, { className: "h-5 w-5" })
11521
+ children: /* @__PURE__ */ jsx42(X, { className: "h-5 w-5" })
10449
11522
  }
10450
11523
  ) }),
10451
- /* @__PURE__ */ jsx41(TooltipContent, { children: "Clear match-any search" })
11524
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "Clear match-any search" })
10452
11525
  ] }) : null
10453
11526
  ] }) : null,
10454
- renderedFacets ? /* @__PURE__ */ jsx41(ToolbarFacets, { facets: renderedFacets }) : null,
10455
- toolbar?.leading ? /* @__PURE__ */ jsx41(
11527
+ renderedFacets ? /* @__PURE__ */ jsx42(ToolbarFacets, { facets: renderedFacets }) : null,
11528
+ toolbar?.leading ? /* @__PURE__ */ jsx42(
10456
11529
  "div",
10457
11530
  {
10458
11531
  "data-matrx-table-toolbar-extras": true,
@@ -10460,13 +11533,13 @@ function MatrxDataTableCore({
10460
11533
  children: toolbar.leading
10461
11534
  }
10462
11535
  ) : null,
10463
- /* @__PURE__ */ jsxs31(
11536
+ /* @__PURE__ */ jsxs32(
10464
11537
  "div",
10465
11538
  {
10466
11539
  "data-matrx-table-actions": true,
10467
11540
  className: "ml-auto flex min-w-0 flex-wrap items-center gap-0",
10468
11541
  children: [
10469
- /* @__PURE__ */ jsx41(
11542
+ /* @__PURE__ */ jsx42(
10470
11543
  TableToolbarAction,
10471
11544
  {
10472
11545
  HostAction: host.ToolbarAction,
@@ -10474,10 +11547,10 @@ function MatrxDataTableCore({
10474
11547
  tooltip: hasActiveFilters ? "Clear search and filters; keep columns and sort" : "No search or filters to clear",
10475
11548
  disabled: !hasActiveFilters,
10476
11549
  onClick: clearAllFilters,
10477
- children: /* @__PURE__ */ jsx41(Eraser, {})
11550
+ children: /* @__PURE__ */ jsx42(Eraser, {})
10478
11551
  }
10479
11552
  ),
10480
- showToolbarCopy && effectiveCopy ? /* @__PURE__ */ jsx41(
11553
+ showToolbarCopy && effectiveCopy ? /* @__PURE__ */ jsx42(
10481
11554
  CopyButtons,
10482
11555
  {
10483
11556
  size: "toolbar",
@@ -10520,17 +11593,17 @@ function MatrxDataTableCore({
10520
11593
  }
10521
11594
  }
10522
11595
  ) : null,
10523
- columns.length > 0 ? /* @__PURE__ */ jsx41(
11596
+ columns.length > 0 ? /* @__PURE__ */ jsx42(
10524
11597
  TableToolbarAction,
10525
11598
  {
10526
11599
  HostAction: host.ToolbarAction,
10527
11600
  ariaLabel: "Columns",
10528
11601
  tooltip: "Show, hide, or reorder columns",
10529
11602
  onClick: () => setColumnManagerOpen(true),
10530
- children: /* @__PURE__ */ jsx41(SlidersHorizontal, {})
11603
+ children: /* @__PURE__ */ jsx42(SlidersHorizontal, {})
10531
11604
  }
10532
11605
  ) : null,
10533
- toolbar?.refresh ? /* @__PURE__ */ jsx41(
11606
+ toolbar?.refresh ? /* @__PURE__ */ jsx42(
10534
11607
  TableToolbarAction,
10535
11608
  {
10536
11609
  HostAction: host.ToolbarAction,
@@ -10552,10 +11625,10 @@ function MatrxDataTableCore({
10552
11625
  setToolbarActionPending((current) => ({ ...current, refresh: false }));
10553
11626
  });
10554
11627
  },
10555
- children: /* @__PURE__ */ jsx41(RefreshControlIcon, { spinning: isFetching || toolbarActionPending.refresh })
11628
+ children: /* @__PURE__ */ jsx42(RefreshControlIcon, { spinning: isFetching || toolbarActionPending.refresh })
10556
11629
  }
10557
11630
  ) : null,
10558
- toolbar?.add ? /* @__PURE__ */ jsx41(
11631
+ toolbar?.add ? /* @__PURE__ */ jsx42(
10559
11632
  TableToolbarAction,
10560
11633
  {
10561
11634
  HostAction: host.ToolbarAction,
@@ -10577,7 +11650,7 @@ function MatrxDataTableCore({
10577
11650
  setToolbarActionPending((current) => ({ ...current, add: false }));
10578
11651
  });
10579
11652
  },
10580
- children: /* @__PURE__ */ jsx41(Plus, {})
11653
+ children: /* @__PURE__ */ jsx42(Plus, {})
10581
11654
  }
10582
11655
  ) : null,
10583
11656
  toolbar?.actions
@@ -10587,15 +11660,15 @@ function MatrxDataTableCore({
10587
11660
  ]
10588
11661
  }
10589
11662
  ),
10590
- 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: [
10591
- /* @__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: [
10592
11665
  formatCount3(selectionCount),
10593
11666
  " ",
10594
11667
  selectionNoun,
10595
11668
  selectionCount === 1 ? "" : "s",
10596
11669
  " selected"
10597
11670
  ] }),
10598
- /* @__PURE__ */ jsxs31(
11671
+ /* @__PURE__ */ jsxs32(
10599
11672
  Button,
10600
11673
  {
10601
11674
  type: "button",
@@ -10607,13 +11680,13 @@ function MatrxDataTableCore({
10607
11680
  selection.onSelectedIdsChange([]);
10608
11681
  },
10609
11682
  children: [
10610
- /* @__PURE__ */ jsx41(X, { className: "h-3.5 w-3.5" }),
11683
+ /* @__PURE__ */ jsx42(X, { className: "h-3.5 w-3.5" }),
10611
11684
  "Clear"
10612
11685
  ]
10613
11686
  }
10614
11687
  ),
10615
- /* @__PURE__ */ jsxs31("div", { className: "ml-auto flex flex-wrap items-center gap-1.5", children: [
10616
- 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(
10617
11690
  CopyButtons,
10618
11691
  {
10619
11692
  size: "icon",
@@ -10646,9 +11719,9 @@ function MatrxDataTableCore({
10646
11719
  selection.actions?.(selectedRows, selection.selectedIds)
10647
11720
  ] })
10648
11721
  ] }) : null,
10649
- /* @__PURE__ */ jsxs31("div", { "data-matrx-table-body-region": true, className: "flex min-h-0 flex-1 flex-col gap-2", children: [
10650
- /* @__PURE__ */ jsxs31("div", { className: "relative min-h-0 flex-1", children: [
10651
- 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(
10652
11725
  "div",
10653
11726
  {
10654
11727
  ref: cardsScrollRef,
@@ -10660,34 +11733,34 @@ function MatrxDataTableCore({
10660
11733
  mobileCardsClass
10661
11734
  ),
10662
11735
  children: [
10663
- isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ jsxs31(
11736
+ isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ jsxs32(
10664
11737
  "div",
10665
11738
  {
10666
11739
  role: "status",
10667
11740
  className: "pointer-events-none absolute inset-x-0 top-0 z-20 h-0.5 overflow-hidden bg-primary/15",
10668
11741
  children: [
10669
- /* @__PURE__ */ jsx41("div", { className: "h-full w-full animate-pulse bg-primary" }),
10670
- /* @__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" })
10671
11744
  ]
10672
11745
  }
10673
11746
  ) : null,
10674
- isLoading ? Array.from({ length: 4 }).map((_, index) => /* @__PURE__ */ jsx41(
11747
+ isLoading ? Array.from({ length: 4 }).map((_, index) => /* @__PURE__ */ jsx42(
10675
11748
  Skeleton,
10676
11749
  {
10677
11750
  className: "h-52 w-full shrink-0 rounded-lg"
10678
11751
  },
10679
11752
  `mobile-card-sk-${index}`
10680
- )) : 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: [
10681
11754
  renderedEmptyState?.icon,
10682
- /* @__PURE__ */ jsx41("p", { className: "text-sm font-medium text-foreground", children: renderedEmptyState?.title ?? "No rows" }),
10683
- 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,
10684
11757
  renderedEmptyState?.action
10685
11758
  ] }) }) : paginated.map((row, index) => {
10686
11759
  const id = getRowId(row);
10687
11760
  const displayRow = applyRowEdits(row, edits[id]);
10688
11761
  const controls = buildRecordControls(displayRow);
10689
11762
  const selectable = selection?.isRowSelectable?.(row) ?? Boolean(selection);
10690
- 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, {
10691
11764
  renderCell: (columnKey) => {
10692
11765
  const column = columns.find((candidate) => columnId(candidate) === columnKey);
10693
11766
  return column ? renderRecordCell(row, column, index) : null;
@@ -10703,14 +11776,14 @@ function MatrxDataTableCore({
10703
11776
  else next.delete(id);
10704
11777
  setSelectedIds(next);
10705
11778
  },
10706
- actions: showInlineRowCopy || rowActions ? /* @__PURE__ */ jsxs31(
11779
+ actions: showInlineRowCopy || rowActions ? /* @__PURE__ */ jsxs32(
10707
11780
  "div",
10708
11781
  {
10709
11782
  "data-matrx-table-row-actions": true,
10710
11783
  className: "inline-flex items-center justify-end gap-0",
10711
11784
  onClick: (event) => event.stopPropagation(),
10712
11785
  children: [
10713
- showInlineRowCopy && effectiveCopy ? /* @__PURE__ */ jsx41(
11786
+ showInlineRowCopy && effectiveCopy ? /* @__PURE__ */ jsx42(
10714
11787
  TableRowCopyControl,
10715
11788
  {
10716
11789
  size: "toolbar",
@@ -10731,7 +11804,7 @@ function MatrxDataTableCore({
10731
11804
  expandedDetail: expandedDetail && isRowExpanded(row) ? expandedDetail.render(displayRow, controls) : null
10732
11805
  }) }, id);
10733
11806
  }),
10734
- appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ jsxs31(
11807
+ appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ jsxs32(
10735
11808
  "div",
10736
11809
  {
10737
11810
  "data-matrx-table-append-loading-card": true,
@@ -10739,7 +11812,7 @@ function MatrxDataTableCore({
10739
11812
  "aria-live": "polite",
10740
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",
10741
11814
  children: [
10742
- /* @__PURE__ */ jsx41(
11815
+ /* @__PURE__ */ jsx42(
10743
11816
  Loader2,
10744
11817
  {
10745
11818
  "aria-hidden": "true",
@@ -10753,7 +11826,7 @@ function MatrxDataTableCore({
10753
11826
  ]
10754
11827
  }
10755
11828
  ) : null,
10756
- /* @__PURE__ */ jsxs31(
11829
+ /* @__PURE__ */ jsxs32(
10757
11830
  "div",
10758
11831
  {
10759
11832
  ref: scrollRef,
@@ -10767,32 +11840,32 @@ function MatrxDataTableCore({
10767
11840
  tableClassName
10768
11841
  ),
10769
11842
  children: [
10770
- hierarchy && draggedRow ? /* @__PURE__ */ jsx41(
11843
+ hierarchy && draggedRow ? /* @__PURE__ */ jsx42(
10771
11844
  HierarchyRootDropTarget,
10772
11845
  {
10773
11846
  label: hierarchy.rootDropLabel ?? "Drop here to move to the top level",
10774
11847
  draggedLabel: hierarchy.itemLabel?.(draggedRow) ?? "Moving row"
10775
11848
  }
10776
11849
  ) : null,
10777
- hierarchy && draggedRowId ? /* @__PURE__ */ jsx41(
11850
+ hierarchy && draggedRowId ? /* @__PURE__ */ jsx42(
10778
11851
  HierarchyDragIndicatorLayer,
10779
11852
  {
10780
11853
  scrollRef,
10781
11854
  resolve: resolveHierarchyMove
10782
11855
  }
10783
11856
  ) : null,
10784
- isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ jsxs31(
11857
+ isFetching && !isLoading && appendQuery === null ? /* @__PURE__ */ jsxs32(
10785
11858
  "div",
10786
11859
  {
10787
11860
  role: "status",
10788
11861
  className: "pointer-events-none absolute inset-x-0 top-0 z-20 h-0.5 overflow-hidden bg-primary/15",
10789
11862
  children: [
10790
- /* @__PURE__ */ jsx41("div", { className: "h-full w-full animate-pulse bg-primary" }),
10791
- /* @__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" })
10792
11865
  ]
10793
11866
  }
10794
11867
  ) : null,
10795
- /* @__PURE__ */ jsxs31(
11868
+ /* @__PURE__ */ jsxs32(
10796
11869
  "table",
10797
11870
  {
10798
11871
  ref: tableRef,
@@ -10810,7 +11883,7 @@ function MatrxDataTableCore({
10810
11883
  fixedLayoutActive && "sm:table-fixed sm:max-w-none sm:w-[var(--matrx-resized-table-width)]"
10811
11884
  ),
10812
11885
  children: [
10813
- /* @__PURE__ */ jsx41(
11886
+ /* @__PURE__ */ jsx42(
10814
11887
  "thead",
10815
11888
  {
10816
11889
  ref: tableHeaderRef,
@@ -10819,14 +11892,14 @@ function MatrxDataTableCore({
10819
11892
  "z-10 border-b border-border bg-muted/90 shadow-[0_1px_0_0_var(--border)] backdrop-blur-sm",
10820
11893
  stickyHeader && (documentStickyHeader ? "relative translate-y-[var(--matrx-document-sticky-offset)]" : "sticky top-0")
10821
11894
  ),
10822
- children: /* @__PURE__ */ jsxs31("tr", { children: [
10823
- selection ? /* @__PURE__ */ jsx41(
11895
+ children: /* @__PURE__ */ jsxs32("tr", { children: [
11896
+ selection ? /* @__PURE__ */ jsx42(
10824
11897
  "th",
10825
11898
  {
10826
11899
  "data-matrx-table-selection-column": true,
10827
11900
  className: "h-9 w-9 px-2 text-left align-middle",
10828
11901
  style: fixedUtilityWidth(fixedTableGeometry?.selectionWidth),
10829
- children: /* @__PURE__ */ jsx41(
11902
+ children: /* @__PURE__ */ jsx42(
10830
11903
  "div",
10831
11904
  {
10832
11905
  "data-matrx-table-selection-target": true,
@@ -10835,7 +11908,7 @@ function MatrxDataTableCore({
10835
11908
  event.currentTarget.querySelector('[role="checkbox"]')?.click();
10836
11909
  }
10837
11910
  },
10838
- children: /* @__PURE__ */ jsx41(
11911
+ children: /* @__PURE__ */ jsx42(
10839
11912
  Checkbox,
10840
11913
  {
10841
11914
  className: CHECKBOX_TAP_AREA,
@@ -10861,7 +11934,7 @@ function MatrxDataTableCore({
10861
11934
  const compact = col.compact || marker !== void 0;
10862
11935
  const width = marker && col.width === void 0 ? 40 : col.width;
10863
11936
  const minWidth = marker && col.minWidth === void 0 ? 40 : col.minWidth;
10864
- return /* @__PURE__ */ jsxs31(
11937
+ return /* @__PURE__ */ jsxs32(
10865
11938
  "th",
10866
11939
  {
10867
11940
  "data-matrx-table-column-id": id,
@@ -10886,12 +11959,17 @@ function MatrxDataTableCore({
10886
11959
  (width !== void 0 || columnResizable) && "sm:w-[var(--matrx-col-w)] sm:min-w-[var(--matrx-col-w)]",
10887
11960
  col.headerClassName,
10888
11961
  isColumnDragShadow && "bg-primary/10 shadow-[inset_2px_0_0_var(--primary),inset_-2px_0_0_var(--primary)]",
10889
- col.align === "center" && "text-center",
10890
- 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
10891
11966
  ),
10892
- style: columnWidthVar(width, effectiveColumnWidths[id], id, columnResizable),
11967
+ style: {
11968
+ ...columnWidthVar(width, effectiveColumnWidths[id], id, columnResizable),
11969
+ ...frozenStyle(id)
11970
+ },
10893
11971
  children: [
10894
- /* @__PURE__ */ jsx41(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: /* @__PURE__ */ jsx41(
11972
+ /* @__PURE__ */ jsx42(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: /* @__PURE__ */ jsx42(
10895
11973
  ColumnHeaderCell,
10896
11974
  {
10897
11975
  label: col.header,
@@ -10930,7 +12008,7 @@ function MatrxDataTableCore({
10930
12008
  reorderColumn: reorderableColumns ? { id, label: headerLabel } : void 0
10931
12009
  }
10932
12010
  ) }),
10933
- columnResizable ? /* @__PURE__ */ jsx41(
12011
+ columnResizable ? /* @__PURE__ */ jsx42(
10934
12012
  ColumnResizeHandle,
10935
12013
  {
10936
12014
  columnId: id,
@@ -10951,22 +12029,22 @@ function MatrxDataTableCore({
10951
12029
  id
10952
12030
  );
10953
12031
  }),
10954
- showActionsCol && /* @__PURE__ */ jsx41(
12032
+ showActionsCol && /* @__PURE__ */ jsx42(
10955
12033
  "th",
10956
12034
  {
10957
12035
  "data-matrx-table-actions-column": true,
10958
12036
  className: "h-9 w-px whitespace-nowrap px-2 text-right align-middle text-xs font-semibold uppercase tracking-wide text-muted-foreground",
10959
12037
  style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth),
10960
- 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" })
10961
12039
  }
10962
12040
  )
10963
12041
  ] })
10964
12042
  }
10965
12043
  ),
10966
- /* @__PURE__ */ jsxs31("tbody", { children: [
10967
- isLoading ? Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs31("tr", { className: "border-b border-border/60", children: [
10968
- 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,
10969
- 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(
10970
12048
  "td",
10971
12049
  {
10972
12050
  className: cn(
@@ -10974,20 +12052,20 @@ function MatrxDataTableCore({
10974
12052
  col.compact || resolveColumnMarker(col) !== void 0 ? "px-1" : "px-2",
10975
12053
  col.mobileHidden && "max-sm:hidden"
10976
12054
  ),
10977
- children: /* @__PURE__ */ jsx41(Skeleton, { className: "h-5 w-full" })
12055
+ children: /* @__PURE__ */ jsx42(Skeleton, { className: "h-5 w-full" })
10978
12056
  },
10979
12057
  columnId(col)
10980
12058
  )),
10981
- showActionsCol && /* @__PURE__ */ jsx41("td", { className: "text-right align-middle", style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth), children: /* @__PURE__ */ jsx41(Skeleton, { className: "ml-auto h-5 w-10" }) })
10982
- ] }, `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(
10983
12061
  "td",
10984
12062
  {
10985
12063
  colSpan: visibleColumns.length + leadingCols + (showActionsCol ? 1 : 0),
10986
12064
  className: "px-0 py-12 text-center",
10987
- 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: [
10988
12066
  renderedEmptyState?.icon,
10989
- /* @__PURE__ */ jsx41("p", { className: "text-sm font-medium text-foreground", children: renderedEmptyState?.title ?? "No rows" }),
10990
- 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,
10991
12069
  renderedEmptyState?.action
10992
12070
  ] })
10993
12071
  }
@@ -10998,7 +12076,7 @@ function MatrxDataTableCore({
10998
12076
  const displayRow = applyRowEdits(row, rowEdits);
10999
12077
  const controls = buildRecordControls(displayRow);
11000
12078
  const isChecked = selectedIdSet.has(id);
11001
- const rowNode = /* @__PURE__ */ jsxs31(
12079
+ const rowNode = /* @__PURE__ */ jsxs32(
11002
12080
  "tr",
11003
12081
  {
11004
12082
  "data-row-id": id,
@@ -11031,16 +12109,28 @@ function MatrxDataTableCore({
11031
12109
  highlightedIndex === index && "bg-muted ring-1 ring-inset ring-primary/60",
11032
12110
  rowClassName?.(row, index),
11033
12111
  draggedRowId === id && "opacity-40",
11034
- 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)
11035
12119
  ),
11036
12120
  children: [
11037
- selection ? /* @__PURE__ */ jsx41(
12121
+ selection ? /* @__PURE__ */ jsx42(
11038
12122
  "td",
11039
12123
  {
11040
- 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
+ ),
11041
12131
  style: fixedUtilityWidth(fixedTableGeometry?.selectionWidth),
11042
12132
  onClick: (e) => e.stopPropagation(),
11043
- children: selection.isRowSelectable?.(row) ?? true ? /* @__PURE__ */ jsx41(
12133
+ children: selection.isRowSelectable?.(row) ?? true ? /* @__PURE__ */ jsx42(
11044
12134
  "div",
11045
12135
  {
11046
12136
  "data-matrx-table-selection-target": true,
@@ -11049,7 +12139,7 @@ function MatrxDataTableCore({
11049
12139
  event.currentTarget.querySelector('[role="checkbox"]')?.click();
11050
12140
  }
11051
12141
  },
11052
- children: /* @__PURE__ */ jsx41(
12142
+ children: /* @__PURE__ */ jsx42(
11053
12143
  Checkbox,
11054
12144
  {
11055
12145
  className: CHECKBOX_TAP_AREA,
@@ -11064,7 +12154,7 @@ function MatrxDataTableCore({
11064
12154
  ) : null,
11065
12155
  visibleColumns.map((col, colIdx) => {
11066
12156
  const isColumnDragShadow = columnDragPreview?.draggedId === columnId(col) && columnDragPreview.targetId !== null;
11067
- return /* @__PURE__ */ jsx41(
12157
+ return /* @__PURE__ */ jsx42(
11068
12158
  "td",
11069
12159
  {
11070
12160
  "data-matrx-table-column-id": columnId(col),
@@ -11079,23 +12169,33 @@ function MatrxDataTableCore({
11079
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)]",
11080
12170
  col.className,
11081
12171
  isColumnDragShadow && "bg-primary/10 shadow-[inset_2px_0_0_var(--primary),inset_-2px_0_0_var(--primary)]",
11082
- col.align === "center" && "text-center",
11083
- 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)
11084
12181
  ),
11085
- style: columnWidthVar(
11086
- resolveColumnMarker(col) && col.width === void 0 ? 40 : col.width,
11087
- effectiveColumnWidths[columnId(col)],
11088
- columnId(col),
11089
- resizableColumns && col.resizable !== false
11090
- ),
11091
- 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(
11092
12192
  "div",
11093
12193
  {
11094
12194
  className: cn(
11095
12195
  colIdx === 0 && hierarchy && "flex min-w-0 items-center"
11096
12196
  ),
11097
12197
  children: [
11098
- colIdx === 0 && hierarchy ? /* @__PURE__ */ jsx41(
12198
+ colIdx === 0 && hierarchy ? /* @__PURE__ */ jsx42(
11099
12199
  HierarchyDragHandle,
11100
12200
  {
11101
12201
  id,
@@ -11103,7 +12203,7 @@ function MatrxDataTableCore({
11103
12203
  disabled: !(hierarchy.canReparent?.(row) ?? true)
11104
12204
  }
11105
12205
  ) : null,
11106
- /* @__PURE__ */ jsx41(
12206
+ /* @__PURE__ */ jsx42(
11107
12207
  "div",
11108
12208
  {
11109
12209
  "data-matrx-cell-content": true,
@@ -11118,20 +12218,20 @@ function MatrxDataTableCore({
11118
12218
  columnId(col)
11119
12219
  );
11120
12220
  }),
11121
- showActionsCol && /* @__PURE__ */ jsx41(
12221
+ showActionsCol && /* @__PURE__ */ jsx42(
11122
12222
  "td",
11123
12223
  {
11124
12224
  "data-matrx-table-row-action-cell": true,
11125
12225
  className: "text-right align-middle",
11126
12226
  style: fixedUtilityWidth(fixedTableGeometry?.actionsWidth),
11127
- children: /* @__PURE__ */ jsxs31(
12227
+ children: /* @__PURE__ */ jsxs32(
11128
12228
  "div",
11129
12229
  {
11130
12230
  "data-matrx-table-row-actions": true,
11131
12231
  className: "inline-flex items-center justify-end gap-0",
11132
12232
  onClick: (e) => e.stopPropagation(),
11133
12233
  children: [
11134
- showInlineRowCopy && effectiveCopy ? /* @__PURE__ */ jsx41(
12234
+ showInlineRowCopy && effectiveCopy ? /* @__PURE__ */ jsx42(
11135
12235
  TableRowCopyControl,
11136
12236
  {
11137
12237
  size: "toolbar",
@@ -11142,8 +12242,8 @@ function MatrxDataTableCore({
11142
12242
  }
11143
12243
  ) : null,
11144
12244
  renderRowActions(displayRow, controls),
11145
- windowEnabled ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11146
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12245
+ windowEnabled ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12246
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11147
12247
  Button,
11148
12248
  {
11149
12249
  type: "button",
@@ -11157,10 +12257,10 @@ function MatrxDataTableCore({
11157
12257
  if (windowConfig?.openOnRowClick === true) openDetail(row);
11158
12258
  else openWindow(row);
11159
12259
  },
11160
- 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" })
11161
12261
  }
11162
12262
  ) }),
11163
- /* @__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" })
11164
12264
  ] }) : null
11165
12265
  ]
11166
12266
  }
@@ -11172,12 +12272,12 @@ function MatrxDataTableCore({
11172
12272
  id
11173
12273
  );
11174
12274
  const wrappedRow = rowWrapper ? rowWrapper(row, rowNode) : rowNode;
11175
- const inlineDetail = expandedDetail && isRowExpanded(row) ? /* @__PURE__ */ jsx41(
12275
+ const inlineDetail = expandedDetail && isRowExpanded(row) ? /* @__PURE__ */ jsx42(
11176
12276
  "tr",
11177
12277
  {
11178
12278
  "data-matrx-table-expanded-detail": id,
11179
12279
  className: cn("bg-muted/20", expandedDetail.className),
11180
- children: /* @__PURE__ */ jsx41(
12280
+ children: /* @__PURE__ */ jsx42(
11181
12281
  "td",
11182
12282
  {
11183
12283
  colSpan: visibleColumns.length + leadingCols + (showActionsCol ? 1 : 0),
@@ -11188,8 +12288,8 @@ function MatrxDataTableCore({
11188
12288
  },
11189
12289
  `${id}:expanded-detail`
11190
12290
  ) : null;
11191
- return hierarchy ? /* @__PURE__ */ jsxs31(Fragment6, { children: [
11192
- /* @__PURE__ */ jsx41(
12291
+ return hierarchy ? /* @__PURE__ */ jsxs32(Fragment6, { children: [
12292
+ /* @__PURE__ */ jsx42(
11193
12293
  HierarchyDroppableRow,
11194
12294
  {
11195
12295
  id,
@@ -11198,24 +12298,24 @@ function MatrxDataTableCore({
11198
12298
  }
11199
12299
  ),
11200
12300
  inlineDetail
11201
- ] }, id) : /* @__PURE__ */ jsxs31(Fragment6, { children: [
12301
+ ] }, id) : /* @__PURE__ */ jsxs32(Fragment6, { children: [
11202
12302
  wrappedRow,
11203
12303
  inlineDetail
11204
12304
  ] }, id);
11205
12305
  }),
11206
- 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(
11207
12307
  "td",
11208
12308
  {
11209
12309
  colSpan: visibleColumns.length + leadingCols + (showActionsCol ? 1 : 0),
11210
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",
11211
- children: /* @__PURE__ */ jsxs31(
12311
+ children: /* @__PURE__ */ jsxs32(
11212
12312
  "div",
11213
12313
  {
11214
12314
  role: "status",
11215
12315
  "aria-live": "polite",
11216
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",
11217
12317
  children: [
11218
- /* @__PURE__ */ jsx41(
12318
+ /* @__PURE__ */ jsx42(
11219
12319
  Loader2,
11220
12320
  {
11221
12321
  "aria-hidden": "true",
@@ -11229,9 +12329,9 @@ function MatrxDataTableCore({
11229
12329
  }
11230
12330
  ) }) : null
11231
12331
  ] }),
11232
- 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: [
11233
- selection ? /* @__PURE__ */ jsx41("td", { className: "px-2 py-2" }) : null,
11234
- 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(
11235
12335
  "td",
11236
12336
  {
11237
12337
  className: cn(
@@ -11251,7 +12351,7 @@ function MatrxDataTableCore({
11251
12351
  },
11252
12352
  columnId(column)
11253
12353
  )),
11254
- showActionsCol ? /* @__PURE__ */ jsx41("td", {}) : null
12354
+ showActionsCol ? /* @__PURE__ */ jsx42("td", {}) : null
11255
12355
  ] }, `footer-${index}`)) }) : null
11256
12356
  ]
11257
12357
  }
@@ -11259,8 +12359,8 @@ function MatrxDataTableCore({
11259
12359
  ]
11260
12360
  }
11261
12361
  ),
11262
- scrollHintLeft ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11263
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12362
+ scrollHintLeft ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12363
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11264
12364
  Button,
11265
12365
  {
11266
12366
  type: "button",
@@ -11271,13 +12371,13 @@ function MatrxDataTableCore({
11271
12371
  "data-matrx-table-scroll-control": "left",
11272
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",
11273
12373
  onClick: () => scrollTableHorizontally("left"),
11274
- children: /* @__PURE__ */ jsx41(ChevronLeft, { className: "h-5 w-5" })
12374
+ children: /* @__PURE__ */ jsx42(ChevronLeft, { className: "h-5 w-5" })
11275
12375
  }
11276
12376
  ) }),
11277
- /* @__PURE__ */ jsx41(TooltipContent, { children: "More columns to the left" })
12377
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "More columns to the left" })
11278
12378
  ] }) : null,
11279
- scrollHintRight ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11280
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12379
+ scrollHintRight ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12380
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11281
12381
  Button,
11282
12382
  {
11283
12383
  type: "button",
@@ -11288,26 +12388,26 @@ function MatrxDataTableCore({
11288
12388
  "data-matrx-table-scroll-control": "right",
11289
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",
11290
12390
  onClick: () => scrollTableHorizontally("right"),
11291
- children: /* @__PURE__ */ jsx41(ChevronRight, { className: "h-5 w-5" })
12391
+ children: /* @__PURE__ */ jsx42(ChevronRight, { className: "h-5 w-5" })
11292
12392
  }
11293
12393
  ) }),
11294
- /* @__PURE__ */ jsx41(TooltipContent, { children: "More columns to the right" })
12394
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "More columns to the right" })
11295
12395
  ] }) : null
11296
12396
  ] }),
11297
- appendQuery ? /* @__PURE__ */ jsxs31(
12397
+ appendQuery ? /* @__PURE__ */ jsxs32(
11298
12398
  "div",
11299
12399
  {
11300
12400
  "data-matrx-table-footer": true,
11301
12401
  className: "flex min-h-8 shrink-0 flex-wrap items-center gap-2 border-t border-border",
11302
12402
  "aria-busy": isLoading || isFetching,
11303
12403
  children: [
11304
- /* @__PURE__ */ jsxs31(
12404
+ /* @__PURE__ */ jsxs32(
11305
12405
  "div",
11306
12406
  {
11307
12407
  ...isFetching && !isLoading ? {} : { role: "status", "aria-live": "polite" },
11308
12408
  className: "flex w-full min-w-0 items-center gap-2 text-xs text-muted-foreground sm:w-auto sm:flex-1",
11309
12409
  children: [
11310
- isLoading ? /* @__PURE__ */ jsx41(
12410
+ isLoading ? /* @__PURE__ */ jsx42(
11311
12411
  Loader2,
11312
12412
  {
11313
12413
  "data-matrx-table-append-loader": true,
@@ -11315,21 +12415,21 @@ function MatrxDataTableCore({
11315
12415
  className: "h-5 w-5 shrink-0 animate-spin text-primary motion-reduce:animate-none"
11316
12416
  }
11317
12417
  ) : null,
11318
- /* @__PURE__ */ jsxs31("div", { className: "flex min-w-0 flex-1 flex-wrap items-center gap-x-2", children: [
11319
- /* @__PURE__ */ jsx41("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)}`}` }),
11320
- appendQuery.pagination.sourceUntil || appendUsesLocalProcessing ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11321
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41("button", { type: "button", "aria-label": "Source coverage", className: "shrink-0 text-xs text-muted-foreground underline decoration-dotted underline-offset-4", children: "Source info" }) }),
11322
- /* @__PURE__ */ jsxs31(TooltipContent, { children: [
11323
- appendQuery.pagination.sourceUntil ? /* @__PURE__ */ jsxs31("p", { children: [
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: [
11324
12424
  "Source fixed through ",
11325
12425
  new Date(appendQuery.pagination.sourceUntil).toLocaleString(),
11326
12426
  "."
11327
12427
  ] }) : null,
11328
- /* @__PURE__ */ jsx41("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." })
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." })
11329
12429
  ] })
11330
12430
  ] }) : null,
11331
- scrollPagination.error ? /* @__PURE__ */ jsx41("p", { role: "alert", className: "text-destructive", children: scrollPagination.error.message }) : null,
11332
- 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: [
11333
12433
  appendScrollPolicy.reason,
11334
12434
  " Load more remains available."
11335
12435
  ] }) : null
@@ -11337,26 +12437,26 @@ function MatrxDataTableCore({
11337
12437
  ]
11338
12438
  }
11339
12439
  ),
11340
- appendQuery.pagination.sourcePageSize ? /* @__PURE__ */ jsxs31(
12440
+ appendQuery.pagination.sourcePageSize ? /* @__PURE__ */ jsxs32(
11341
12441
  Select,
11342
12442
  {
11343
12443
  value: String(appendQuery.pagination.sourcePageSize.value),
11344
12444
  onValueChange: (value) => appendQuery.pagination.sourcePageSize?.onChange(Number(value)),
11345
12445
  children: [
11346
- /* @__PURE__ */ jsx41(
12446
+ /* @__PURE__ */ jsx42(
11347
12447
  SelectTrigger,
11348
12448
  {
11349
12449
  "aria-label": "Rows per load",
11350
12450
  className: "h-8 min-w-20 shrink-0 rounded-md border border-border bg-card px-3 text-sm [&_svg]:size-5",
11351
12451
  disabled: isLoading || isFetching || appendQuery.pagination.loadAll?.isLoading,
11352
- children: /* @__PURE__ */ jsx41(SelectValue, {})
12452
+ children: /* @__PURE__ */ jsx42(SelectValue, {})
11353
12453
  }
11354
12454
  ),
11355
- /* @__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)) })
11356
12456
  ]
11357
12457
  }
11358
12458
  ) : null,
11359
- appendQuery.pagination.loadAll?.isLoading ? /* @__PURE__ */ jsx41(
12459
+ appendQuery.pagination.loadAll?.isLoading ? /* @__PURE__ */ jsx42(
11360
12460
  Button,
11361
12461
  {
11362
12462
  type: "button",
@@ -11365,7 +12465,7 @@ function MatrxDataTableCore({
11365
12465
  onClick: appendQuery.pagination.loadAll.stop,
11366
12466
  children: "Stop loading"
11367
12467
  }
11368
- ) : scrollPagination.error ? /* @__PURE__ */ jsx41(
12468
+ ) : scrollPagination.error ? /* @__PURE__ */ jsx42(
11369
12469
  Button,
11370
12470
  {
11371
12471
  type: "button",
@@ -11374,8 +12474,8 @@ function MatrxDataTableCore({
11374
12474
  onClick: appendQuery.pagination.retrySource ?? (appendQuery.pagination.hasNextPage ? appendQuery.pagination.loadNextPage : appendQuery.pagination.refresh),
11375
12475
  children: appendQuery.pagination.retrySource ? "Retry source" : appendQuery.pagination.hasNextPage ? "Retry" : "Reload rows"
11376
12476
  }
11377
- ) : appendQuery.pagination.hasNextPage || scrollPagination.error ? /* @__PURE__ */ jsxs31("div", { className: "flex min-w-0 max-w-full flex-wrap gap-0", children: [
11378
- /* @__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(
11379
12479
  Button,
11380
12480
  {
11381
12481
  type: "button",
@@ -11386,7 +12486,7 @@ function MatrxDataTableCore({
11386
12486
  children: "Load more"
11387
12487
  }
11388
12488
  ),
11389
- appendQuery.pagination.loadAll ? /* @__PURE__ */ jsx41(
12489
+ appendQuery.pagination.loadAll ? /* @__PURE__ */ jsx42(
11390
12490
  Button,
11391
12491
  {
11392
12492
  type: "button",
@@ -11397,10 +12497,10 @@ function MatrxDataTableCore({
11397
12497
  children: "Load all"
11398
12498
  }
11399
12499
  ) : null
11400
- ] }) : !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
11401
12501
  ]
11402
12502
  }
11403
- ) : !hidePagination && (totalItems > 0 || sourceTotal !== void 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(
11404
12504
  GenericTablePagination,
11405
12505
  {
11406
12506
  totalItems,
@@ -11427,7 +12527,7 @@ function MatrxDataTableCore({
11427
12527
  }
11428
12528
  ) }) : null
11429
12529
  ] }),
11430
- /* @__PURE__ */ jsx41(
12530
+ /* @__PURE__ */ jsx42(
11431
12531
  ColumnManager,
11432
12532
  {
11433
12533
  open: columnManagerOpen,
@@ -11438,7 +12538,7 @@ function MatrxDataTableCore({
11438
12538
  onApply: commitColumnState
11439
12539
  }
11440
12540
  ),
11441
- detailEnabled && selectedRow ? /* @__PURE__ */ jsx41(
12541
+ detailEnabled && selectedRow ? /* @__PURE__ */ jsx42(
11442
12542
  SidePanelSurface,
11443
12543
  {
11444
12544
  title: resolveStringTitle(
@@ -11449,8 +12549,8 @@ function MatrxDataTableCore({
11449
12549
  description: detail?.description?.(selectedRow),
11450
12550
  onClose: () => setSelectedId(null),
11451
12551
  defaultWidth: detail?.defaultWidth ?? 480,
11452
- headerActions: /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-1", children: [
11453
- effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx41(
12552
+ headerActions: /* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-1", children: [
12553
+ effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx42(
11454
12554
  TableRowCopyControl,
11455
12555
  {
11456
12556
  size: "icon",
@@ -11462,8 +12562,8 @@ function MatrxDataTableCore({
11462
12562
  }
11463
12563
  ) : null,
11464
12564
  detail?.headerActions?.(selectedRow),
11465
- windowEnabled ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11466
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12565
+ windowEnabled ? /* @__PURE__ */ jsxs32(Tooltip, { children: [
12566
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11467
12567
  Button,
11468
12568
  {
11469
12569
  type: "button",
@@ -11473,10 +12573,10 @@ function MatrxDataTableCore({
11473
12573
  className: "h-7 w-7",
11474
12574
  "aria-label": "Open in window",
11475
12575
  onClick: () => openWindow(selectedRow),
11476
- children: /* @__PURE__ */ jsx41(PanelRight, { className: "h-5 w-5" })
12576
+ children: /* @__PURE__ */ jsx42(PanelRight, { className: "h-5 w-5" })
11477
12577
  }
11478
12578
  ) }),
11479
- /* @__PURE__ */ jsx41(TooltipContent, { children: "Open in window" })
12579
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "Open in window" })
11480
12580
  ] }) : null
11481
12581
  ] }),
11482
12582
  children: detail?.render ? (
@@ -11487,7 +12587,7 @@ function MatrxDataTableCore({
11487
12587
  // fixes the whole class at once — a custom body that already
11488
12588
  // scrolls (`h-full` + `overflow-y-auto` root) still resolves to
11489
12589
  // this container's height, so no second scrollbar appears.
11490
- /* @__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, {
11491
12591
  closeDetail: () => setSelectedId(null),
11492
12592
  openDetail: () => openDetail(selectedRow),
11493
12593
  openWindow: () => openWindow(selectedRow),
@@ -11495,7 +12595,7 @@ function MatrxDataTableCore({
11495
12595
  hasPendingEdits: Boolean(edits[getRowId(selectedRow)]),
11496
12596
  discardPendingEdits: () => discardRowEdits(getRowId(selectedRow))
11497
12597
  }) })
11498
- ) : /* @__PURE__ */ jsx41(
12598
+ ) : /* @__PURE__ */ jsx42(
11499
12599
  DataRowInspector,
11500
12600
  {
11501
12601
  row: selectedRow,
@@ -11507,7 +12607,7 @@ function MatrxDataTableCore({
11507
12607
  )
11508
12608
  }
11509
12609
  ) : null,
11510
- windowRow ? /* @__PURE__ */ jsx41(
12610
+ windowRow ? /* @__PURE__ */ jsx42(
11511
12611
  DataRowWindow,
11512
12612
  {
11513
12613
  isOpen: true,
@@ -11518,9 +12618,9 @@ function MatrxDataTableCore({
11518
12618
  height: windowConfig?.height,
11519
12619
  windowId: `matrx-data-row-${urlState?.id ?? "local"}-${getRowId(windowRow)}`,
11520
12620
  defaultTab: windowConfig?.defaultTab,
11521
- headerActions: /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-1", children: [
11522
- windowConfig?.openOnRowClick === true && detail?.enabled === true ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11523
- /* @__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(
11524
12624
  Button,
11525
12625
  {
11526
12626
  type: "button",
@@ -11533,12 +12633,12 @@ function MatrxDataTableCore({
11533
12633
  closeWindow();
11534
12634
  openDetail(windowRow);
11535
12635
  },
11536
- children: /* @__PURE__ */ jsx41(PanelRightOpen, { className: "h-5 w-5" })
12636
+ children: /* @__PURE__ */ jsx42(PanelRightOpen, { className: "h-5 w-5" })
11537
12637
  }
11538
12638
  ) }),
11539
- /* @__PURE__ */ jsx41(TooltipContent, { children: "Open in side panel" })
12639
+ /* @__PURE__ */ jsx42(TooltipContent, { children: "Open in side panel" })
11540
12640
  ] }) : null,
11541
- effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx41(
12641
+ effectiveCopy && showRowCopy ? /* @__PURE__ */ jsx42(
11542
12642
  TableRowCopyControl,
11543
12643
  {
11544
12644
  size: "icon",
@@ -11557,7 +12657,7 @@ function MatrxDataTableCore({
11557
12657
  closeWindow,
11558
12658
  hasPendingEdits: Boolean(edits[getRowId(windowRow)]),
11559
12659
  discardPendingEdits: () => discardRowEdits(getRowId(windowRow))
11560
- }) ?? /* @__PURE__ */ jsx41(
12660
+ }) ?? /* @__PURE__ */ jsx42(
11561
12661
  DataRowInspector,
11562
12662
  {
11563
12663
  row: windowRow,
@@ -11593,15 +12693,15 @@ function MatrxDataTableCore({
11593
12693
  })
11594
12694
  }
11595
12695
  ) : null,
11596
- editEnabled ? /* @__PURE__ */ jsxs31(Fragment7, { children: [
11597
- foreignDrafts.length > 0 ? /* @__PURE__ */ jsxs31(
12696
+ editEnabled ? /* @__PURE__ */ jsxs32(Fragment7, { children: [
12697
+ foreignDrafts.length > 0 ? /* @__PURE__ */ jsxs32(
11598
12698
  "div",
11599
12699
  {
11600
12700
  "data-matrx-foreign-drafts": true,
11601
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",
11602
12702
  children: [
11603
- /* @__PURE__ */ jsx41("span", { children: "Unsaved edits from previous results" }),
11604
- /* @__PURE__ */ jsx41(
12703
+ /* @__PURE__ */ jsx42("span", { children: "Unsaved edits from previous results" }),
12704
+ /* @__PURE__ */ jsx42(
11605
12705
  CopyButtons,
11606
12706
  {
11607
12707
  size: "xs",
@@ -11610,11 +12710,11 @@ function MatrxDataTableCore({
11610
12710
  json: () => foreignDraftPayload
11611
12711
  }
11612
12712
  ),
11613
- /* @__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" })
11614
12714
  ]
11615
12715
  }
11616
12716
  ) : null,
11617
- /* @__PURE__ */ jsx41(
12717
+ /* @__PURE__ */ jsx42(
11618
12718
  ConfirmDialog,
11619
12719
  {
11620
12720
  open: confirmForeignDraftDiscard,
@@ -11634,7 +12734,7 @@ function MatrxDataTableCore({
11634
12734
  }
11635
12735
  }
11636
12736
  ),
11637
- /* @__PURE__ */ jsx41(
12737
+ /* @__PURE__ */ jsx42(
11638
12738
  DirtySavePill,
11639
12739
  {
11640
12740
  changeCount,
@@ -11647,11 +12747,11 @@ function MatrxDataTableCore({
11647
12747
  ]
11648
12748
  }
11649
12749
  ),
11650
- /* @__PURE__ */ jsx41(DragOverlay, { children: draggedRow ? (
12750
+ /* @__PURE__ */ jsx42(DragOverlay, { children: draggedRow ? (
11651
12751
  // w-max: the overlay inherits the ACTIVE node's size, and the active
11652
12752
  // node is the 16px grip handle — without it the label wraps to one
11653
12753
  // character per line.
11654
- /* @__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" })
11655
12755
  ) : null })
11656
12756
  ]
11657
12757
  }
@@ -11666,7 +12766,7 @@ function HierarchyDragHandle({
11666
12766
  id,
11667
12767
  disabled
11668
12768
  });
11669
- return /* @__PURE__ */ jsx41(
12769
+ return /* @__PURE__ */ jsx42(
11670
12770
  "button",
11671
12771
  {
11672
12772
  ref: setNodeRef,
@@ -11678,7 +12778,7 @@ function HierarchyDragHandle({
11678
12778
  onClick: (event) => event.stopPropagation(),
11679
12779
  ...attributes,
11680
12780
  ...listeners,
11681
- children: /* @__PURE__ */ jsx41(GripVertical, { className: "h-3.5 w-3.5" })
12781
+ children: /* @__PURE__ */ jsx42(GripVertical, { className: "h-3.5 w-3.5" })
11682
12782
  }
11683
12783
  );
11684
12784
  }
@@ -11687,7 +12787,7 @@ function HierarchyRootDropTarget({
11687
12787
  draggedLabel
11688
12788
  }) {
11689
12789
  const { isOver, setNodeRef } = useDroppable2({ id: "__root__" });
11690
- return /* @__PURE__ */ jsxs31(
12790
+ return /* @__PURE__ */ jsxs32(
11691
12791
  "div",
11692
12792
  {
11693
12793
  ref: setNodeRef,
@@ -11697,8 +12797,8 @@ function HierarchyRootDropTarget({
11697
12797
  isOver && "border-solid bg-primary/20 shadow-md shadow-primary/25"
11698
12798
  ),
11699
12799
  children: [
11700
- /* @__PURE__ */ jsx41("span", { className: "truncate", children: draggedLabel }),
11701
- /* @__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 })
11702
12802
  ]
11703
12803
  }
11704
12804
  );
@@ -11747,7 +12847,7 @@ function HierarchyDragIndicatorLayer({
11747
12847
  const { preview: preview2 } = indicator;
11748
12848
  const indent = indicator.left + 10 + preview2.depth * 12;
11749
12849
  if (preview2.position === "inside") {
11750
- return /* @__PURE__ */ jsx41(
12850
+ return /* @__PURE__ */ jsx42(
11751
12851
  "div",
11752
12852
  {
11753
12853
  "aria-hidden": "true",
@@ -11759,7 +12859,7 @@ function HierarchyDragIndicatorLayer({
11759
12859
  width: Math.max(0, indicator.width - 4),
11760
12860
  height: indicator.height
11761
12861
  },
11762
- children: /* @__PURE__ */ jsxs31(
12862
+ children: /* @__PURE__ */ jsxs32(
11763
12863
  "span",
11764
12864
  {
11765
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",
@@ -11774,7 +12874,7 @@ function HierarchyDragIndicatorLayer({
11774
12874
  );
11775
12875
  }
11776
12876
  const lineTop = preview2.position === "before" ? indicator.top - 1 : indicator.top + indicator.height - 1;
11777
- return /* @__PURE__ */ jsx41(
12877
+ return /* @__PURE__ */ jsx42(
11778
12878
  "div",
11779
12879
  {
11780
12880
  "aria-hidden": "true",
@@ -11785,9 +12885,9 @@ function HierarchyDragIndicatorLayer({
11785
12885
  left: indent,
11786
12886
  width: Math.max(0, indicator.left + indicator.width - indent - 8)
11787
12887
  },
11788
- children: /* @__PURE__ */ jsxs31("div", { className: "relative h-0.5 rounded-full bg-primary", children: [
11789
- /* @__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" }),
11790
- /* @__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(
11791
12891
  "span",
11792
12892
  {
11793
12893
  className: cn(
@@ -11828,7 +12928,7 @@ function ColumnHeaderDropZone({
11828
12928
  disabled: !enabled,
11829
12929
  data: { matrxDragKind: "column-header", columnId: id }
11830
12930
  });
11831
- 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 });
11832
12932
  }
11833
12933
  function fixedUtilityWidth(width) {
11834
12934
  return width === void 0 ? void 0 : { width: `${width}px`, minWidth: `${width}px`, maxWidth: `${width}px` };
@@ -11862,9 +12962,9 @@ function DefaultJsonCell({ value }) {
11862
12962
  const Viewer = host.JsonViewer;
11863
12963
  const text = JSON.stringify(value, null, 2);
11864
12964
  const summary = Array.isArray(value) ? `${value.length} items` : Object.keys(value).slice(0, 3).join(", ") || "Empty object";
11865
- return /* @__PURE__ */ jsxs31(Fragment7, { children: [
11866
- /* @__PURE__ */ jsxs31(Tooltip, { children: [
11867
- /* @__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) => {
11868
12968
  event.stopPropagation();
11869
12969
  setOpen(true);
11870
12970
  }, style: { display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden", whiteSpace: "normal", overflowWrap: "anywhere" }, "aria-label": "Open JSON value", children: [
@@ -11872,9 +12972,9 @@ function DefaultJsonCell({ value }) {
11872
12972
  " ",
11873
12973
  summary
11874
12974
  ] }) }),
11875
- /* @__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 })
11876
12976
  ] }),
11877
- /* @__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 }) })
11878
12978
  ] });
11879
12979
  }
11880
12980
  function DefaultMarkerCell({
@@ -11883,8 +12983,8 @@ function DefaultMarkerCell({
11883
12983
  }) {
11884
12984
  const label = marker === "favorite" ? value ? "Favorite" : "Not favorite" : value ? "Pinned" : "Not pinned";
11885
12985
  const Icon3 = marker === "favorite" ? Star : Pin;
11886
- return /* @__PURE__ */ jsxs31(Tooltip, { children: [
11887
- /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
12986
+ return /* @__PURE__ */ jsxs32(Tooltip, { children: [
12987
+ /* @__PURE__ */ jsx42(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx42(
11888
12988
  "span",
11889
12989
  {
11890
12990
  role: "img",
@@ -11893,21 +12993,23 @@ function DefaultMarkerCell({
11893
12993
  "inline-flex size-5 items-center justify-center",
11894
12994
  value ? "text-amber-500" : "text-muted-foreground/45"
11895
12995
  ),
11896
- children: /* @__PURE__ */ jsx41(Icon3, { className: "size-4", ...value ? { fill: "currentColor" } : {} })
12996
+ children: /* @__PURE__ */ jsx42(Icon3, { className: "size-4", ...value ? { fill: "currentColor" } : {} })
11897
12997
  }
11898
12998
  ) }),
11899
- /* @__PURE__ */ jsx41(TooltipContent, { children: label })
12999
+ /* @__PURE__ */ jsx42(TooltipContent, { children: label })
11900
13000
  ] });
11901
13001
  }
11902
13002
  function renderCell(row, col, index) {
11903
13003
  if (col.cell) return col.cell(row, index);
11904
13004
  const raw = getCellValue(row, col);
13005
+ const formattedByDeclaration = formatColumnValue(col, raw);
13006
+ if (formattedByDeclaration) return /* @__PURE__ */ jsx42(FormattedCell, { result: formattedByDeclaration });
11905
13007
  const kind = col.cellKind ?? "auto";
11906
13008
  const asUuid = kind === "uuid" || kind === "fk" || kind === "auto" && isUuidValue(raw);
11907
13009
  if (asUuid && typeof raw === "string") {
11908
13010
  const forbidden = typeof col.fk?.forbidden === "function" ? col.fk.forbidden(raw, row) : Boolean(col.fk?.forbidden);
11909
13011
  const declaredToken = typeof col.fk?.token === "function" ? col.fk.token(row) : col.fk?.token;
11910
- return /* @__PURE__ */ jsx41(
13012
+ return /* @__PURE__ */ jsx42(
11911
13013
  MatrxUuidCell,
11912
13014
  {
11913
13015
  value: raw,
@@ -11919,16 +13021,16 @@ function renderCell(row, col, index) {
11919
13021
  }
11920
13022
  );
11921
13023
  }
11922
- 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 });
11923
13025
  if (typeof raw === "boolean") {
11924
13026
  const marker = resolveColumnMarker(col);
11925
- if (marker) return /* @__PURE__ */ jsx41(DefaultMarkerCell, { marker, value: raw });
11926
- 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" });
11927
13029
  }
11928
13030
  const formatted = formatTableDisplayValue(raw);
11929
- return /* @__PURE__ */ jsxs31(Tooltip, { children: [
11930
- /* @__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 }) }),
11931
- /* @__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 })
11932
13034
  ] });
11933
13035
  }
11934
13036
  function resolveStringTitle(title, fallback) {
@@ -11943,14 +13045,14 @@ import { useId as useId3, useState as useState22 } from "react";
11943
13045
  // src/dropdown-menu.tsx
11944
13046
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
11945
13047
  import * as React17 from "react";
11946
- import { jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
13048
+ import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
11947
13049
  var DropdownMenu = DropdownMenuPrimitive.Root;
11948
13050
  var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
11949
13051
  var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
11950
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";
11951
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";
11952
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";
11953
- var DropdownMenuSubTrigger = React17.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs32(
13055
+ var DropdownMenuSubTrigger = React17.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs33(
11954
13056
  DropdownMenuPrimitive.SubTrigger,
11955
13057
  {
11956
13058
  ref,
@@ -11963,12 +13065,12 @@ var DropdownMenuSubTrigger = React17.forwardRef(({ className, inset, children, .
11963
13065
  ...props,
11964
13066
  children: [
11965
13067
  children,
11966
- /* @__PURE__ */ jsx42(RadixChevronRightIcon, { className: "ml-auto h-4 w-4" })
13068
+ /* @__PURE__ */ jsx43(RadixChevronRightIcon, { className: "ml-auto h-4 w-4" })
11967
13069
  ]
11968
13070
  }
11969
13071
  ));
11970
13072
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
11971
- var DropdownMenuSubContent = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx42(
13073
+ var DropdownMenuSubContent = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx43(
11972
13074
  DropdownMenuPrimitive.SubContent,
11973
13075
  {
11974
13076
  ref,
@@ -11980,7 +13082,7 @@ var DropdownMenuSubContent = React17.forwardRef(({ className, ...props }, ref) =
11980
13082
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
11981
13083
  var DropdownMenuContent = React17.forwardRef(({ className, sideOffset = 4, container, ...props }, ref) => {
11982
13084
  const portalContainer = usePortalContainer(container);
11983
- return /* @__PURE__ */ jsx42(DropdownMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx42(
13085
+ return /* @__PURE__ */ jsx43(DropdownMenuPrimitive.Portal, { container: portalContainer, children: /* @__PURE__ */ jsx43(
11984
13086
  DropdownMenuPrimitive.Content,
11985
13087
  {
11986
13088
  ref,
@@ -11997,7 +13099,7 @@ var DropdownMenuContent = React17.forwardRef(({ className, sideOffset = 4, conta
11997
13099
  ) });
11998
13100
  });
11999
13101
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
12000
- var DropdownMenuItem = React17.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx42(
13102
+ var DropdownMenuItem = React17.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx43(
12001
13103
  DropdownMenuPrimitive.Item,
12002
13104
  {
12003
13105
  ref,
@@ -12007,7 +13109,7 @@ var DropdownMenuItem = React17.forwardRef(({ className, inset, ...props }, ref)
12007
13109
  }
12008
13110
  ));
12009
13111
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
12010
- var DropdownMenuCheckboxItem = React17.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs32(
13112
+ var DropdownMenuCheckboxItem = React17.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs33(
12011
13113
  DropdownMenuPrimitive.CheckboxItem,
12012
13114
  {
12013
13115
  ref,
@@ -12015,13 +13117,13 @@ var DropdownMenuCheckboxItem = React17.forwardRef(({ className, children, ...pro
12015
13117
  className: cn(MENU_INDICATOR_ITEM_CLASS, className),
12016
13118
  ...props,
12017
13119
  children: [
12018
- /* @__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" }) }) }),
12019
13121
  children
12020
13122
  ]
12021
13123
  }
12022
13124
  ));
12023
13125
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
12024
- var DropdownMenuRadioItem = React17.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs32(
13126
+ var DropdownMenuRadioItem = React17.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs33(
12025
13127
  DropdownMenuPrimitive.RadioItem,
12026
13128
  {
12027
13129
  ref,
@@ -12029,13 +13131,13 @@ var DropdownMenuRadioItem = React17.forwardRef(({ className, children, ...props
12029
13131
  className: cn(MENU_INDICATOR_ITEM_CLASS, className),
12030
13132
  ...props,
12031
13133
  children: [
12032
- /* @__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" }) }) }),
12033
13135
  children
12034
13136
  ]
12035
13137
  }
12036
13138
  ));
12037
13139
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
12038
- var DropdownMenuLabel = React17.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx42(
13140
+ var DropdownMenuLabel = React17.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx43(
12039
13141
  DropdownMenuPrimitive.Label,
12040
13142
  {
12041
13143
  ref,
@@ -12045,7 +13147,7 @@ var DropdownMenuLabel = React17.forwardRef(({ className, inset, ...props }, ref)
12045
13147
  }
12046
13148
  ));
12047
13149
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
12048
- var DropdownMenuSeparator = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx42(
13150
+ var DropdownMenuSeparator = React17.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx43(
12049
13151
  DropdownMenuPrimitive.Separator,
12050
13152
  {
12051
13153
  ref,
@@ -12058,7 +13160,7 @@ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
12058
13160
  var DropdownMenuShortcut = ({
12059
13161
  className,
12060
13162
  ...props
12061
- }) => /* @__PURE__ */ jsx42(
13163
+ }) => /* @__PURE__ */ jsx43(
12062
13164
  "span",
12063
13165
  {
12064
13166
  "data-slot": "dropdown-menu-shortcut",
@@ -12069,7 +13171,7 @@ var DropdownMenuShortcut = ({
12069
13171
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
12070
13172
 
12071
13173
  // src/data-table/SavedViewsControl.tsx
12072
- import { jsx as jsx43, jsxs as jsxs33 } from "react/jsx-runtime";
13174
+ import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
12073
13175
  function SavedViewsControl({
12074
13176
  views,
12075
13177
  activeId = null,
@@ -12127,10 +13229,10 @@ function SavedViewsControl({
12127
13229
  }
12128
13230
  };
12129
13231
  const activeName = activeId ? views.find((view) => view.id === activeId)?.name : void 0;
12130
- return /* @__PURE__ */ jsxs33("div", { className: "flex min-w-0 flex-wrap items-center gap-1", "data-matrx-table-saved-views": true, children: [
12131
- /* @__PURE__ */ jsxs33(DropdownMenu, { children: [
12132
- /* @__PURE__ */ jsxs33(Tooltip, { children: [
12133
- /* @__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(
12134
13236
  Button,
12135
13237
  {
12136
13238
  type: "button",
@@ -12141,38 +13243,38 @@ function SavedViewsControl({
12141
13243
  "aria-describedby": dirty ? unsavedChangesId : void 0,
12142
13244
  disabled: saving,
12143
13245
  children: [
12144
- /* @__PURE__ */ jsx43("span", { className: "min-w-0 flex-1 truncate", children: loading ? "Loading views\u2026" : activeName ?? "Default view" }),
12145
- dirty ? /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: "size-1.5 shrink-0 rounded-full bg-amber-500" }) : null,
12146
- /* @__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" })
12147
13249
  ]
12148
13250
  }
12149
13251
  ) }) }),
12150
- /* @__PURE__ */ jsx43(TooltipContent, { children: "Choose or save a table view" })
13252
+ /* @__PURE__ */ jsx44(TooltipContent, { children: "Choose or save a table view" })
12151
13253
  ] }),
12152
- /* @__PURE__ */ jsxs33(DropdownMenuContent, { align: "end", children: [
12153
- /* @__PURE__ */ jsx43(DropdownMenuLabel, { children: "Views" }),
12154
- /* @__PURE__ */ jsxs33(DropdownMenuRadioGroup, { value: activeId ?? "__default__", onValueChange: (value) => onSelect(value === "__default__" ? null : value), children: [
12155
- /* @__PURE__ */ jsx43(DropdownMenuRadioItem, { value: "__default__", children: "Default view" }),
12156
- 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))
12157
13259
  ] }),
12158
- /* @__PURE__ */ jsx43(DropdownMenuSeparator, {}),
12159
- /* @__PURE__ */ jsx43(DropdownMenuItem, { disabled: saving, onSelect: () => {
13260
+ /* @__PURE__ */ jsx44(DropdownMenuSeparator, {}),
13261
+ /* @__PURE__ */ jsx44(DropdownMenuItem, { disabled: saving, onSelect: () => {
12160
13262
  setActionError(null);
12161
13263
  setSaveOpen(true);
12162
13264
  }, children: "Save current view\u2026" }),
12163
- activeId && onUpdate ? /* @__PURE__ */ jsx43(DropdownMenuItem, { disabled: saving, onSelect: () => void update(), children: "Update current view" }) : null,
12164
- 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
12165
13267
  ] })
12166
13268
  ] }),
12167
- 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,
12168
- visibleError ? /* @__PURE__ */ jsx43("p", { role: "alert", className: "basis-full break-words text-xs text-destructive", children: visibleError }) : null,
12169
- /* @__PURE__ */ jsx43(Dialog, { open: saveOpen, onOpenChange: setSaveOpen, children: /* @__PURE__ */ jsxs33(DialogContent, { children: [
12170
- /* @__PURE__ */ jsx43(DialogHeader, { children: /* @__PURE__ */ jsx43(DialogTitle, { children: "Save current view" }) }),
12171
- visibleError ? /* @__PURE__ */ jsx43("p", { role: "alert", className: "text-sm text-destructive", children: visibleError }) : null,
12172
- /* @__PURE__ */ jsx43(Input, { "aria-label": "View name", value: name, onChange: (event) => setName(event.target.value), placeholder: "View name", autoFocus: true }),
12173
- /* @__PURE__ */ jsxs33(DialogFooter, { children: [
12174
- /* @__PURE__ */ jsx43(Button, { type: "button", variant: "outline", onClick: () => setSaveOpen(false), children: "Cancel" }),
12175
- /* @__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" })
12176
13278
  ] })
12177
13279
  ] }) })
12178
13280
  ] });
@@ -12214,32 +13316,61 @@ function downloadTableAsXlsx({
12214
13316
  URL.revokeObjectURL(url);
12215
13317
  }
12216
13318
  export {
13319
+ BOOLEAN_TRUE_COLOR,
13320
+ CELL_TINT_CLASS,
13321
+ COLOR_RULE_OPS,
13322
+ COLOR_RULE_OP_LABELS,
12217
13323
  DataRowInspector,
12218
13324
  DataRowWindow,
13325
+ EMPTY_TABLE_STYLE,
13326
+ FORMAT_MISMATCH_CLASS,
13327
+ FormattedCell,
12219
13328
  GenericTablePagination,
12220
13329
  MatrxDataTable,
12221
13330
  MatrxDataTableProvider,
12222
13331
  MatrxTableRowAlchemyProvider,
12223
13332
  MatrxUuidCell,
13333
+ NO_FROZEN_COLUMNS,
13334
+ OPS_WITH_VALUE,
13335
+ ROW_TINT_CLASS,
13336
+ STYLE_COLORS,
13337
+ STYLE_COLOR_LABELS,
13338
+ SWATCH_CLASS,
12224
13339
  SavedViewsControl,
13340
+ TABLE_STYLE_METADATA_KEY,
13341
+ TABLE_STYLE_VERSION,
12225
13342
  TableTitleRow,
12226
13343
  TableViewTabs,
13344
+ alignForFormat,
13345
+ applyStylePath,
12227
13346
  buildRowAgentInput,
12228
13347
  buildViewAgentInput,
12229
13348
  buildViewHuman,
12230
13349
  collectSelectOptions,
13350
+ colorForChoice,
12231
13351
  downloadTableAsXlsx,
13352
+ evaluateRule,
12232
13353
  filterKindLabel,
13354
+ formatColumnValue,
12233
13355
  inferTableSearchRole,
13356
+ isStyleColor,
13357
+ parseTableStyle,
12234
13358
  parseTableViewSnapshot,
13359
+ pixelWidth,
12235
13360
  rankTableSearchRows,
13361
+ resolveCellColor,
12236
13362
  resolveColumnMarker,
12237
13363
  resolveFilterKind,
13364
+ resolveFrozenColumns,
13365
+ resolveRowColor,
12238
13366
  resolveTableSearchScopes,
12239
13367
  rowsToCsvFromColumns,
12240
13368
  rowsToMarkdownTable,
12241
13369
  rowsToRecordsFromColumns,
12242
13370
  shortUuid,
13371
+ stylePath,
13372
+ tableStyleFromMetadata,
13373
+ tableStyleIsEmpty,
12243
13374
  tableUrlParamPrefix,
12244
13375
  useMatrxDataTableHost,
12245
13376
  useMatrxTableRowAlchemy,