@tensor_1/react 2.50.0 → 2.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -131,6 +131,7 @@ __export(src_exports, {
131
131
  DiffViewer: () => DiffViewer,
132
132
  DisplayPreferences: () => DisplayPreferences,
133
133
  Drawer: () => Drawer,
134
+ ENUM_FILTER_OPERATORS: () => ENUM_FILTER_OPERATORS,
134
135
  EmptyState: () => EmptyState,
135
136
  EntityPicker: () => EntityPicker,
136
137
  ErrorState: () => ErrorState,
@@ -325,6 +326,7 @@ __export(src_exports, {
325
326
  edgeLabelSize: () => edgeLabelSize,
326
327
  emptyFilterValue: () => emptyFilterValue,
327
328
  encodeQr: () => encodeQr,
329
+ enumColumnFilter: () => enumColumnFilter,
328
330
  enumerateDateKeys: () => enumerateDateKeys,
329
331
  enumerateDateSpan: () => enumerateDateSpan,
330
332
  fileKind: () => fileKind,
@@ -637,6 +639,9 @@ function toggleSort(keys, field, additive = false) {
637
639
  if (!existing) return [...keys, { field, dir }];
638
640
  return keys.map((k) => k.field === field ? { field, dir } : k);
639
641
  }
642
+ function enumColumnFilter(field, value) {
643
+ return { field, kind: "enum", op: value.operator === "is-none-of" ? "isNoneOf" : "isAnyOf", value: [...value.values] };
644
+ }
640
645
  function asNum(v) {
641
646
  return typeof v === "number" ? v : Number(v);
642
647
  }
@@ -10902,7 +10907,7 @@ var TableWrap = (0, import_react69.forwardRef)(function TableWrap2({ announcemen
10902
10907
  ] });
10903
10908
  });
10904
10909
  function Table({
10905
- density = "standard",
10910
+ density,
10906
10911
  zebra = true,
10907
10912
  pinnedCol,
10908
10913
  pinnedActions,
@@ -10924,7 +10929,7 @@ function Table({
10924
10929
  fixed && "uix-table--fixed",
10925
10930
  className
10926
10931
  ),
10927
- "data-density": density !== "standard" ? density : void 0,
10932
+ "data-density": density,
10928
10933
  "data-uix-rowpeek": rowPeek || void 0,
10929
10934
  "data-uix-table-v2": v2 || void 0,
10930
10935
  ...props,
@@ -14070,6 +14075,7 @@ var DEFAULT_FILTER_SUMMARY_LABELS = {
14070
14075
  until: "until {to}",
14071
14076
  more: "{first} +{count}",
14072
14077
  preset: "{label}",
14078
+ noneOf: "not {values}",
14073
14079
  on: "{date}",
14074
14080
  before: "before {date}",
14075
14081
  after: "after {date}"
@@ -14077,6 +14083,7 @@ var DEFAULT_FILTER_SUMMARY_LABELS = {
14077
14083
  var TEXT_FILTER_OPERATORS = ["contains", "not-contains", "is", "is-not", "starts-with"];
14078
14084
  var NUMBER_FILTER_OPERATORS = ["eq", "neq", "lt", "lte", "gt", "gte", "between"];
14079
14085
  var DATE_FILTER_OPERATORS = ["on", "before", "after", "between"];
14086
+ var ENUM_FILTER_OPERATORS = ["is-any-of", "is-none-of"];
14080
14087
  function emptyFilterValue(kind) {
14081
14088
  switch (kind) {
14082
14089
  case "enum":
@@ -14158,7 +14165,7 @@ async function resolveFilterLabels(field, value) {
14158
14165
  return { kind: "reference", values: value.values.map((v) => resolved.has(v.value) ? { value: v.value, label: resolved.get(v.value) } : v) };
14159
14166
  }
14160
14167
  function matchFilterPreset(field, value) {
14161
- if (value?.kind !== "enum" || !field.presets?.length) return void 0;
14168
+ if (value?.kind !== "enum" || value.operator === "is-none-of" || !field.presets?.length) return void 0;
14162
14169
  const chosen = new Set(value.values);
14163
14170
  return field.presets.find((preset) => {
14164
14171
  const wanted = new Set(preset.values);
@@ -14181,7 +14188,10 @@ function summarizeFilter(field, input, options = {}) {
14181
14188
  const preset = matchFilterPreset(field, value);
14182
14189
  if (preset) return fill3(labels.preset ?? DEFAULT_FILTER_SUMMARY_LABELS.preset, { label: preset.label, field: field.label });
14183
14190
  const byValue = new Map((field.options ?? []).map((o) => [o.value, o.label]));
14184
- return `${field.label}: ${list(value.values.map((v) => byValue.get(v) ?? v))}`;
14191
+ const named = list(value.values.map((v) => byValue.get(v) ?? v));
14192
+ const condition = value.operator ?? (field.enumOperators?.length === 1 ? field.enumOperators[0] : "is-any-of");
14193
+ if (condition === "is-none-of") return `${field.label}: ${fill3(labels.noneOf ?? DEFAULT_FILTER_SUMMARY_LABELS.noneOf, { values: named, field: field.label })}`;
14194
+ return `${field.label}: ${named}`;
14185
14195
  }
14186
14196
  case "reference":
14187
14197
  return `${field.label}: ${list(value.values.map((v) => v.label))}`;
@@ -14262,6 +14272,7 @@ var DEFAULT_FILTER_EDITOR_LABELS = {
14262
14272
  addTagHint: "Enter or a comma adds it.",
14263
14273
  date: "Date",
14264
14274
  dateOperators: { on: "on", before: "before", after: "after", between: "between" },
14275
+ enumOperators: { "is-any-of": "is any of", "is-none-of": "is none of" },
14265
14276
  operators: {
14266
14277
  contains: "contains",
14267
14278
  "not-contains": "does not contain",
@@ -14284,7 +14295,8 @@ function FilterEditor({ field, value: valueProp, onValueChange, onApply, onClear
14284
14295
  ...provided,
14285
14296
  ...labelOverrides,
14286
14297
  operators: { ...DEFAULT_FILTER_EDITOR_LABELS.operators, ...provided?.operators, ...labelOverrides?.operators },
14287
- dateOperators: { ...DEFAULT_FILTER_EDITOR_LABELS.dateOperators, ...provided?.dateOperators, ...labelOverrides?.dateOperators }
14298
+ dateOperators: { ...DEFAULT_FILTER_EDITOR_LABELS.dateOperators, ...provided?.dateOperators, ...labelOverrides?.dateOperators },
14299
+ enumOperators: { ...DEFAULT_FILTER_EDITOR_LABELS.enumOperators, ...provided?.enumOperators, ...labelOverrides?.enumOperators }
14288
14300
  };
14289
14301
  const id = (0, import_react88.useId)();
14290
14302
  let value = valueProp?.kind === field.kind ? valueProp : emptyFilterValue(field.kind);
@@ -14387,16 +14399,30 @@ function EnumBody({ field, value, onChange, labels, threshold }) {
14387
14399
  return q ? options.filter((o) => foldForSearch(o.label).text.includes(q)) : options;
14388
14400
  }, [options, query]);
14389
14401
  const selected = new Set(value.values);
14390
- const toggle = (v, on) => onChange({ kind: "enum", values: on ? [...value.values, v] : value.values.filter((x) => x !== v) });
14402
+ const ops = (field.enumOperators ?? []).filter((op) => ENUM_FILTER_OPERATORS.includes(op));
14403
+ const condition = value.operator ?? (ops.length === 1 ? ops[0] : void 0);
14404
+ const withValues = (values) => condition && condition !== "is-any-of" ? { kind: "enum", values, operator: condition } : { kind: "enum", values };
14405
+ const toggle = (v, on) => onChange(withValues(on ? [...value.values, v] : value.values.filter((x) => x !== v)));
14391
14406
  const presets = field.presets ?? [];
14392
14407
  const active = matchFilterPreset(field, value);
14408
+ const words2 = labels.enumOperators ?? {};
14393
14409
  return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(import_jsx_runtime99.Fragment, { children: [
14394
- presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "uix-chip-group uix-filter-editor__presets", role: "group", "aria-label": labels.presets ?? DEFAULT_FILTER_EDITOR_LABELS.presets, children: presets.map((p) => /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Chip, { pressed: p === active, onPressedChange: () => onChange({ kind: "enum", values: [...p.values] }), children: p.label }, p.id)) }),
14410
+ ops.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "uix-filter-editor__row", children: /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
14411
+ Select,
14412
+ {
14413
+ size: "sm",
14414
+ "aria-label": labels.operator,
14415
+ value: value.operator ?? "is-any-of",
14416
+ options: ops.map((op) => ({ value: op, label: words2[op] ?? DEFAULT_FILTER_EDITOR_LABELS.enumOperators[op] })),
14417
+ onValueChange: (op) => onChange(op === "is-none-of" ? { kind: "enum", values: value.values, operator: "is-none-of" } : { kind: "enum", values: value.values })
14418
+ }
14419
+ ) }),
14420
+ presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "uix-chip-group uix-filter-editor__presets", role: "group", "aria-label": labels.presets ?? DEFAULT_FILTER_EDITOR_LABELS.presets, children: presets.map((p) => /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Chip, { pressed: p === active, onPressedChange: () => onChange(withValues([...p.values])), children: p.label }, p.id)) }),
14395
14421
  options.length > threshold && /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Input, { type: "search", size: "sm", "aria-label": labels.search, placeholder: labels.search, value: query, onChange: (e) => setQuery(e.currentTarget.value), autoFocus: true }),
14396
14422
  /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)("div", { className: "uix-filter-editor__bulk", children: [
14397
14423
  /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("span", { className: "uix-filter-editor__count", "aria-live": "polite", children: fillLabel(labels.selected, { count: value.values.length }) }),
14398
- /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Button, { type: "button", variant: "link", size: "sm", onClick: () => onChange({ kind: "enum", values: [.../* @__PURE__ */ new Set([...value.values, ...shown.map((o) => o.value)])] }), children: labels.selectAll }),
14399
- /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Button, { type: "button", variant: "link", size: "sm", onClick: () => onChange({ kind: "enum", values: [] }), children: labels.selectNone })
14424
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Button, { type: "button", variant: "link", size: "sm", onClick: () => onChange(withValues([.../* @__PURE__ */ new Set([...value.values, ...shown.map((o) => o.value)])])), children: labels.selectAll }),
14425
+ /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Button, { type: "button", variant: "link", size: "sm", onClick: () => onChange(withValues([])), children: labels.selectNone })
14400
14426
  ] }),
14401
14427
  /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("div", { className: "uix-filter-editor__list", children: shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime99.jsx)("p", { className: "uix-filter-editor__note", children: labels.noMatches }) : shown.map((o) => /* @__PURE__ */ (0, import_jsx_runtime99.jsx)(Checkbox, { label: o.label, checked: selected.has(o.value), onChange: (e) => toggle(o.value, e.currentTarget.checked) }, o.value)) })
14402
14428
  ] });
@@ -14592,6 +14618,7 @@ function DataWorkspace({
14592
14618
  label,
14593
14619
  rows,
14594
14620
  getRowId,
14621
+ rowLabel,
14595
14622
  columns,
14596
14623
  idColumn,
14597
14624
  sort,
@@ -14753,7 +14780,11 @@ function DataWorkspace({
14753
14780
  onSelectionChange(apply(new Set(selected), rowIds, on));
14754
14781
  };
14755
14782
  const atCap = selected.size >= cap;
14756
- const actionsByRow = (0, import_react89.useMemo)(() => rowActions ? shownRows.map((row) => rowActions(row)) : [], [shownRows, rowActions]);
14783
+ const actionsByRow = (0, import_react89.useMemo)(() => {
14784
+ if (!rowActions) return [];
14785
+ const context = { ladder, compact: ladder === "priority-mid" };
14786
+ return shownRows.map((row) => rowActions(row, context));
14787
+ }, [shownRows, rowActions, ladder]);
14757
14788
  const hasActions = actionsByRow.some((node) => node != null && node !== false);
14758
14789
  const activeFilters = filters ? filters.fields.filter((field) => !isFilterEmpty(filters.values[field.id])) : [];
14759
14790
  const searching = (search?.value.trim() ?? "") !== "";
@@ -14780,7 +14811,8 @@ function DataWorkspace({
14780
14811
  onSortChange(next);
14781
14812
  };
14782
14813
  const showSaveAs = onSaveViewAs != null && (viewChanged || saveViewAs === "always");
14783
- const toolbar = /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: "uix-toolbar uix-data-workspace__toolbar", role: "toolbar", "aria-label": label, children: [
14814
+ const hasToolbar = savedViews != null || viewChanged && onSaveView != null || showSaveAs || filters != null || search != null || viewMenu != null || onMaximizedChange != null || toolbarEnd != null && toolbarEnd !== false;
14815
+ const toolbar = hasToolbar && /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("div", { className: "uix-toolbar uix-data-workspace__toolbar", role: "toolbar", "aria-label": label, children: [
14784
14816
  savedViews && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(PopoverButton, { id: `${id}-views`, label: savedViews.current, title: typeof savedViews.current === "string" ? fillLabel(labels.savedView, { name: savedViews.current }) : void 0, variant: "secondary", children: (close) => /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
14785
14817
  savedViews.note != null && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("div", { className: "uix-data-workspace__views-note", children: savedViews.note }),
14786
14818
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(SavedViewMenu, { ...savedViews.menu, onSelect: (viewId) => {
@@ -14840,6 +14872,7 @@ function DataWorkspace({
14840
14872
  collapsed,
14841
14873
  onToggleGroup: toggleGroupOpen,
14842
14874
  getRowId,
14875
+ rowLabel,
14843
14876
  columns,
14844
14877
  idColumn,
14845
14878
  getRowProps,
@@ -14931,6 +14964,7 @@ function WorkspaceTable({
14931
14964
  collapsed,
14932
14965
  onToggleGroup,
14933
14966
  getRowId,
14967
+ rowLabel,
14934
14968
  columns,
14935
14969
  idColumn,
14936
14970
  getRowProps,
@@ -15152,20 +15186,75 @@ function WorkspaceTable({
15152
15186
  const selectRowLabel = labels.selectRow;
15153
15187
  const openLabel = labels.open;
15154
15188
  const fixedOn = fixed && !cards;
15189
+ const [actionsTooWide, setActionsTooWide] = (0, import_react89.useState)(false);
15155
15190
  const [actionsWidth, setActionsWidth] = (0, import_react89.useState)(null);
15156
- useIsomorphicLayoutEffect22(() => {
15157
- if (!fixedOn || !hasActions) return;
15158
- let widest = 0;
15159
- for (const td of Array.from(wrapRef.current?.querySelectorAll("tbody td.uix-table__actions") ?? [])) {
15191
+ const measureActions = !cards && hasActions;
15192
+ const measureConfig = (0, import_react89.useRef)({ measureActions, fixedOn, hasActions });
15193
+ measureConfig.current = { measureActions, fixedOn, hasActions };
15194
+ const measureActionsNow = (0, import_react89.useRef)(() => {
15195
+ });
15196
+ measureActionsNow.current = () => {
15197
+ const wrap = wrapRef.current;
15198
+ const { measureActions: on, fixedOn: fixedNow, hasActions: any } = measureConfig.current;
15199
+ if (!wrap) return;
15200
+ const cells = Array.from(wrap.querySelectorAll("tbody td.uix-table__actions"));
15201
+ if (!on) setActionsTooWide(false);
15202
+ else {
15203
+ let widest = 0;
15204
+ for (const td of cells) if (typeof td.getBoundingClientRect === "function") widest = Math.max(widest, td.getBoundingClientRect().width, td.scrollWidth);
15205
+ if (wrap.clientWidth > 0 && widest > 0) setActionsTooWide(widest > wrap.clientWidth / 4);
15206
+ }
15207
+ if (!fixedNow || !any || typeof document.createRange !== "function" || typeof getComputedStyle !== "function") return;
15208
+ if (typeof document.createRange().getBoundingClientRect !== "function") return;
15209
+ let content = 0;
15210
+ for (const td of cells) {
15160
15211
  const range = document.createRange();
15161
15212
  range.selectNodeContents(td);
15162
- const content = range.getBoundingClientRect().width;
15163
15213
  const style = getComputedStyle(td);
15164
- widest = Math.max(widest, content + parseFloat(style.paddingLeft || "0") + parseFloat(style.paddingRight || "0"));
15214
+ content = Math.max(content, range.getBoundingClientRect().width + parseFloat(style.paddingLeft || "0") + parseFloat(style.paddingRight || "0"));
15165
15215
  }
15166
- const next = widest > 0 ? Math.ceil(widest) : null;
15167
- if (next !== actionsWidth) setActionsWidth(next);
15168
- });
15216
+ const next = content > 0 ? Math.ceil(content) : null;
15217
+ setActionsWidth((current) => current === next ? current : next);
15218
+ };
15219
+ useIsomorphicLayoutEffect22(() => {
15220
+ const wrap = wrapRef.current;
15221
+ if (!wrap) return;
15222
+ let frame = 0;
15223
+ const schedule = () => {
15224
+ if (frame || typeof requestAnimationFrame !== "function") return;
15225
+ frame = requestAnimationFrame(() => {
15226
+ frame = 0;
15227
+ measureActionsNow.current();
15228
+ });
15229
+ };
15230
+ const resize = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(schedule);
15231
+ const collect = () => {
15232
+ if (!resize) return;
15233
+ resize.disconnect();
15234
+ resize.observe(wrap);
15235
+ const table = wrap.querySelector("table");
15236
+ if (table) resize.observe(table);
15237
+ for (const td of Array.from(wrap.querySelectorAll("tbody td.uix-table__actions"))) {
15238
+ resize.observe(td);
15239
+ for (const child of Array.from(td.children)) resize.observe(child);
15240
+ }
15241
+ };
15242
+ collect();
15243
+ const mutation = typeof MutationObserver === "undefined" ? null : new MutationObserver(() => {
15244
+ collect();
15245
+ schedule();
15246
+ });
15247
+ mutation?.observe(wrap, { childList: true, subtree: true });
15248
+ return () => {
15249
+ resize?.disconnect();
15250
+ mutation?.disconnect();
15251
+ if (frame && typeof cancelAnimationFrame === "function") cancelAnimationFrame(frame);
15252
+ };
15253
+ }, []);
15254
+ const rowSet = ids.join("\0");
15255
+ useIsomorphicLayoutEffect22(() => {
15256
+ measureActionsNow.current();
15257
+ }, [measureActions, fixedOn, ladder, rowSet]);
15169
15258
  const actionsCol = actionsWidth != null ? `${actionsWidth}px` : "5.25rem";
15170
15259
  const floors = fixedOn ? [
15171
15260
  ...selectable ? ["var(--uix-selcol-w)"] : [],
@@ -15174,6 +15263,32 @@ function WorkspaceTable({
15174
15263
  ...hasActions ? [actionsCol] : []
15175
15264
  ] : [];
15176
15265
  const tableStyle = fixedOn && floors.length ? { minWidth: floors.length === 1 ? floors[0] : `calc(${floors.join(" + ")})` } : void 0;
15266
+ const sortProps = (column, columnSortable) => {
15267
+ const order = keys.findIndex((key) => key.columnId === column.id);
15268
+ const canSort = columnSortable && sortable;
15269
+ const ordinal = keys.length > 1 && order >= 0 ? order + 1 : void 0;
15270
+ return {
15271
+ sortable: canSort,
15272
+ sortDirection: sortFor(column),
15273
+ sortOrder: ordinal,
15274
+ sortOrderLabel: ordinal != null ? fillLabel(labels.sortPriority, { n: ordinal }) : void 0,
15275
+ onSort: () => {
15276
+ cycleSort(column, multi && additive.current);
15277
+ additive.current = false;
15278
+ },
15279
+ ...canSort && multi ? {
15280
+ onKeyDownCapture: (event) => {
15281
+ if (event.key === "Enter" || event.key === " ") shiftKey.current = event.shiftKey;
15282
+ },
15283
+ // A click made by Enter or Space has no pointer (detail 0) and may not carry Shift itself.
15284
+ onClickCapture: (event) => {
15285
+ additive.current = event.shiftKey || event.detail === 0 && shiftKey.current;
15286
+ shiftKey.current = false;
15287
+ }
15288
+ } : {}
15289
+ };
15290
+ };
15291
+ const idSortColumn = idColumn ? { id: idColumn.id ?? "id", header: idColumn.header, cell: () => null } : null;
15177
15292
  const renderRow = (row, index) => {
15178
15293
  const rowId = ids[index];
15179
15294
  const isSelected = selected.has(rowId);
@@ -15182,6 +15297,7 @@ function WorkspaceTable({
15182
15297
  {
15183
15298
  row,
15184
15299
  rowId,
15300
+ rowLabel,
15185
15301
  columns,
15186
15302
  idColumn,
15187
15303
  getRowProps,
@@ -15276,7 +15392,7 @@ function WorkspaceTable({
15276
15392
  density,
15277
15393
  zebra,
15278
15394
  pinnedCol: frozen,
15279
- pinnedActions: hasActions && !cards,
15395
+ pinnedActions: hasActions && !cards && !actionsTooWide,
15280
15396
  fixed: fixedOn || void 0,
15281
15397
  style: tableStyle,
15282
15398
  className: cx(
@@ -15309,36 +15425,16 @@ function WorkspaceTable({
15309
15425
  onChange: () => toggleMany(ids, onPage < ids.length && !atCap)
15310
15426
  }
15311
15427
  ) }),
15312
- idColumn && /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Th, { scope: "col", "data-col": ladderOn ? "id" : void 0, children: idColumn.header }),
15428
+ idColumn && (idColumn.sortable && idSortColumn ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Th, { scope: "col", "data-col": ladderOn ? "id" : void 0, ...sortProps(idSortColumn, true), children: idColumn.header }) : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Th, { scope: "col", "data-col": ladderOn ? "id" : void 0, children: idColumn.header })),
15313
15429
  columns.map((column) => {
15314
- const order = keys.findIndex((key) => key.columnId === column.id);
15315
- const canSort = column.sortable && sortable;
15316
15430
  const style = !fixedOn && (column.width || column.minWidth) ? { width: column.width, minWidth: column.minWidth } : void 0;
15317
- const ordinal = keys.length > 1 && order >= 0 ? order + 1 : void 0;
15318
15431
  return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(
15319
15432
  Th,
15320
15433
  {
15321
15434
  scope: "col",
15322
15435
  className: cx(column.align === "end" && "uix-col--num", column.className) || void 0,
15323
15436
  style,
15324
- sortable: canSort,
15325
- sortDirection: sortFor(column),
15326
- sortOrder: ordinal,
15327
- sortOrderLabel: ordinal != null ? fillLabel(labels.sortPriority, { n: ordinal }) : void 0,
15328
- onSort: () => {
15329
- cycleSort(column, multi && additive.current);
15330
- additive.current = false;
15331
- },
15332
- ...canSort && multi ? {
15333
- onKeyDownCapture: (event) => {
15334
- if (event.key === "Enter" || event.key === " ") shiftKey.current = event.shiftKey;
15335
- },
15336
- // A click made by Enter or Space has no pointer (detail 0) and may not carry Shift itself.
15337
- onClickCapture: (event) => {
15338
- additive.current = event.shiftKey || event.detail === 0 && shiftKey.current;
15339
- shiftKey.current = false;
15340
- }
15341
- } : {},
15437
+ ...sortProps(column, column.sortable === true),
15342
15438
  ...ladderAttrs(ladderOn, column, false),
15343
15439
  children: column.header
15344
15440
  },
@@ -15357,6 +15453,7 @@ function WorkspaceTable({
15357
15453
  function WorkspaceRowInner({
15358
15454
  row,
15359
15455
  rowId,
15456
+ rowLabel,
15360
15457
  columns,
15361
15458
  idColumn,
15362
15459
  getRowProps,
@@ -15374,7 +15471,7 @@ function WorkspaceRowInner({
15374
15471
  tabStop,
15375
15472
  handlers: handlers2
15376
15473
  }) {
15377
- const text = idColumn?.text(row) ?? rowId;
15474
+ const text = idColumn?.text(row) ?? rowLabel?.(row) ?? rowId;
15378
15475
  const extra = getRowProps?.(row);
15379
15476
  const navProps = nav ? {
15380
15477
  tabIndex: tabStop ? 0 : -1,
@@ -15415,6 +15512,7 @@ function WorkspaceRowInner({
15415
15512
  var WorkspaceRow = (0, import_react89.memo)(WorkspaceRowInner);
15416
15513
  function IdCell({ row, text, idColumn, openLabel }) {
15417
15514
  const rich = idColumn.render ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-data-workspace__id-text", children: idColumn.render(row) }) : null;
15515
+ const label = /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-data-workspace__id-label", children: text });
15418
15516
  const arrow = idColumn.href && renderUixLink(idColumn.renderLink, {
15419
15517
  href: idColumn.href(row),
15420
15518
  className: "uix-data-workspace__open",
@@ -15426,18 +15524,20 @@ function IdCell({ row, text, idColumn, openLabel }) {
15426
15524
  href: idColumn.href(row),
15427
15525
  className: "uix-id-cell__btn uix-data-workspace__id-link",
15428
15526
  children: /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)(import_jsx_runtime100.Fragment, { children: [
15429
- rich ?? text,
15527
+ rich ?? label,
15430
15528
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(ArrowUpRight, {})
15431
15529
  ] })
15432
15530
  }) });
15433
15531
  }
15434
15532
  return /* @__PURE__ */ (0, import_jsx_runtime100.jsxs)("span", { className: "uix-data-workspace__id", children: [
15435
- idColumn.onPeek ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("button", { type: "button", className: "uix-id-cell__btn", "aria-haspopup": "dialog", onClick: () => idColumn.onPeek?.(row), children: rich ?? text }) : rich ?? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-cell-strong", children: text }),
15533
+ idColumn.onPeek ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("button", { type: "button", className: "uix-id-cell__btn", "aria-haspopup": "dialog", onClick: () => idColumn.onPeek?.(row), children: rich ?? label }) : rich ?? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-cell-strong uix-data-workspace__id-label", children: text }),
15436
15534
  arrow
15437
15535
  ] });
15438
15536
  }
15439
15537
  var cssEscape = (value) => typeof CSS !== "undefined" && CSS.escape ? CSS.escape(value) : value.replace(/["\\]/g, "\\$&");
15440
15538
  function Footer({ pagination, labels, rowCount }) {
15539
+ const provided = useUixLabels().pagination;
15540
+ const pagerLabels = provided || pagination.labels ? { ...provided, ...pagination.labels } : void 0;
15441
15541
  const sizes = pagination.pageSizes;
15442
15542
  const size = pagination.mode === "offset" ? pagination.pageSize : pagination.pageSize;
15443
15543
  const rangeText = pagination.mode === "offset" ? fillLabel(labels.range, {
@@ -15452,7 +15552,7 @@ function Footer({ pagination, labels, rowCount }) {
15452
15552
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Select, { size: "sm", value: String(size), onValueChange: (v) => pagination.onPageSizeChange?.(Number(v)), options: sizes.map((s) => ({ value: String(s), label: String(s) })) })
15453
15553
  ] }),
15454
15554
  /* @__PURE__ */ (0, import_jsx_runtime100.jsx)("span", { className: "uix-toolbar__spacer" }),
15455
- pagination.mode === "offset" ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Pagination, { mode: "offset", page: pagination.page, pageCount: Math.max(1, Math.ceil(pagination.total / pagination.pageSize)), onChange: pagination.onPageChange }) : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Pagination, { mode: "cursor", hasPrevious: pagination.hasPrevious, hasNext: pagination.hasNext, onFirst: pagination.onFirst, onPrevious: pagination.onPrevious, onNext: pagination.onNext, summary: pagination.summary })
15555
+ pagination.mode === "offset" ? /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Pagination, { mode: "offset", page: pagination.page, pageCount: Math.max(1, Math.ceil(pagination.total / pagination.pageSize)), onChange: pagination.onPageChange, labels: pagerLabels }) : /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(Pagination, { mode: "cursor", hasPrevious: pagination.hasPrevious, hasNext: pagination.hasNext, onFirst: pagination.onFirst, onPrevious: pagination.onPrevious, onNext: pagination.onNext, summary: pagination.summary, labels: pagerLabels })
15456
15556
  ] });
15457
15557
  }
15458
15558
  function PopoverButton({ id, label, title, variant, children }) {
@@ -15477,7 +15577,9 @@ function PopoverButton({ id, label, title, variant, children }) {
15477
15577
  }
15478
15578
  function ChipSummary({ field, value, options }) {
15479
15579
  const resolved = useResolvedFilterLabels(field, value);
15480
- return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_jsx_runtime100.Fragment, { children: summarizeFilter(resolved.field, resolved.value, options) });
15580
+ const provided = useUixLabels().filterSummary;
15581
+ const merged = provided ? { ...options, labels: { ...provided, ...options?.labels, operators: { ...provided.operators, ...options?.labels?.operators } } } : options;
15582
+ return /* @__PURE__ */ (0, import_jsx_runtime100.jsx)(import_jsx_runtime100.Fragment, { children: summarizeFilter(resolved.field, resolved.value, merged) });
15481
15583
  }
15482
15584
  function openInside(root) {
15483
15585
  try {
@@ -24657,6 +24759,7 @@ function TextDiff({
24657
24759
  DiffViewer,
24658
24760
  DisplayPreferences,
24659
24761
  Drawer,
24762
+ ENUM_FILTER_OPERATORS,
24660
24763
  EmptyState,
24661
24764
  EntityPicker,
24662
24765
  ErrorState,
@@ -24851,6 +24954,7 @@ function TextDiff({
24851
24954
  edgeLabelSize,
24852
24955
  emptyFilterValue,
24853
24956
  encodeQr,
24957
+ enumColumnFilter,
24854
24958
  enumerateDateKeys,
24855
24959
  enumerateDateSpan,
24856
24960
  fileKind,