@ai-matrx/design-system 0.21.10 → 0.21.11

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.
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { h as MatrxDataTableProps, i as TableViewSnapshot, c as MatrxDataTableRecordControls, j as ColumnMarker, M as MatrxColumnDef } from '../types-BAJiOaQL.cjs';
4
- export { A as AnyOfColumnSearch, k as CellEditType, l as CellEditsMap, f as ColumnFilterKind, a as ColumnFilterValue, C as ColumnFiltersState, m as MatrxDataTableContextMenuConfig, g as MatrxDataTableCopyConfig, d as MatrxDataTableDensity, n as MatrxDataTableDetailConfig, o as MatrxDataTableEditConfig, p as MatrxDataTableEmptyState, q as MatrxDataTableFilterUi, r as MatrxDataTableHierarchyConfig, s as MatrxDataTableHierarchyMove, t as MatrxDataTableMobileCardControls, u as MatrxDataTableQueryControl, e as MatrxDataTableQueryState, v as MatrxDataTableSelectionConfig, w as MatrxDataTableSourceProcessing, x as MatrxDataTableToolbar, y as MatrxDataTableUrlStateConfig, z as MatrxDataTableWindowConfig, B as MatrxTablePagination, D as SortDirection, S as SortState, b as TableSavedViewsProps, T as TableSearchMatchMode, E as TableViewQuery, F as TextFilterMode, G as ToolbarFacet } from '../types-BAJiOaQL.cjs';
3
+ import { h as MatrxDataTableProps, i as TableViewSnapshot, c as MatrxDataTableRecordControls, j as ColumnMarker, M as MatrxColumnDef } from '../types-9Ii-b9EJ.cjs';
4
+ export { A as AnyOfColumnSearch, k as CellEditType, l as CellEditsMap, f as ColumnFilterKind, a as ColumnFilterValue, C as ColumnFiltersState, m as MatrxDataTableContextMenuConfig, g as MatrxDataTableCopyConfig, d as MatrxDataTableDensity, n as MatrxDataTableDetailConfig, o as MatrxDataTableEditConfig, p as MatrxDataTableEmptyState, q as MatrxDataTableExpandedDetailConfig, r as MatrxDataTableFilterUi, s as MatrxDataTableHierarchyConfig, t as MatrxDataTableHierarchyMove, u as MatrxDataTableMobileCardControls, v as MatrxDataTableQueryControl, e as MatrxDataTableQueryState, w as MatrxDataTableSelectionConfig, x as MatrxDataTableSourceProcessing, y as MatrxDataTableToolbar, z as MatrxDataTableUrlStateConfig, B as MatrxDataTableWindowConfig, D as MatrxTablePagination, E as SortDirection, S as SortState, b as TableSavedViewsProps, T as TableSearchMatchMode, F as TableViewQuery, G as TextFilterMode, H as ToolbarFacet } from '../types-9Ii-b9EJ.cjs';
5
5
  export { MatrxDataTableHost, MatrxDataTableProvider, MatrxTableRowAlchemy, TableDoors, TableEntityRefProps, TableLinkProps, TablePeekProps, TableSidePanelProps, TableToolbarActionProps, TableWindowPanelProps, useMatrxDataTableHost, useMatrxTableRowAlchemy } from './host.cjs';
6
6
  import { CopyControlProps } from './copy-types.cjs';
7
7
  export { AgentPayloadInput } from './copy-types.cjs';
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { h as MatrxDataTableProps, i as TableViewSnapshot, c as MatrxDataTableRecordControls, j as ColumnMarker, M as MatrxColumnDef } from '../types-Da781-Wq.js';
4
- export { A as AnyOfColumnSearch, k as CellEditType, l as CellEditsMap, f as ColumnFilterKind, a as ColumnFilterValue, C as ColumnFiltersState, m as MatrxDataTableContextMenuConfig, g as MatrxDataTableCopyConfig, d as MatrxDataTableDensity, n as MatrxDataTableDetailConfig, o as MatrxDataTableEditConfig, p as MatrxDataTableEmptyState, q as MatrxDataTableFilterUi, r as MatrxDataTableHierarchyConfig, s as MatrxDataTableHierarchyMove, t as MatrxDataTableMobileCardControls, u as MatrxDataTableQueryControl, e as MatrxDataTableQueryState, v as MatrxDataTableSelectionConfig, w as MatrxDataTableSourceProcessing, x as MatrxDataTableToolbar, y as MatrxDataTableUrlStateConfig, z as MatrxDataTableWindowConfig, B as MatrxTablePagination, D as SortDirection, S as SortState, b as TableSavedViewsProps, T as TableSearchMatchMode, E as TableViewQuery, F as TextFilterMode, G as ToolbarFacet } from '../types-Da781-Wq.js';
3
+ import { h as MatrxDataTableProps, i as TableViewSnapshot, c as MatrxDataTableRecordControls, j as ColumnMarker, M as MatrxColumnDef } from '../types-wy1EEaeG.js';
4
+ export { A as AnyOfColumnSearch, k as CellEditType, l as CellEditsMap, f as ColumnFilterKind, a as ColumnFilterValue, C as ColumnFiltersState, m as MatrxDataTableContextMenuConfig, g as MatrxDataTableCopyConfig, d as MatrxDataTableDensity, n as MatrxDataTableDetailConfig, o as MatrxDataTableEditConfig, p as MatrxDataTableEmptyState, q as MatrxDataTableExpandedDetailConfig, r as MatrxDataTableFilterUi, s as MatrxDataTableHierarchyConfig, t as MatrxDataTableHierarchyMove, u as MatrxDataTableMobileCardControls, v as MatrxDataTableQueryControl, e as MatrxDataTableQueryState, w as MatrxDataTableSelectionConfig, x as MatrxDataTableSourceProcessing, y as MatrxDataTableToolbar, z as MatrxDataTableUrlStateConfig, B as MatrxDataTableWindowConfig, D as MatrxTablePagination, E as SortDirection, S as SortState, b as TableSavedViewsProps, T as TableSearchMatchMode, F as TableViewQuery, G as TextFilterMode, H as ToolbarFacet } from '../types-wy1EEaeG.js';
5
5
  export { MatrxDataTableHost, MatrxDataTableProvider, MatrxTableRowAlchemy, TableDoors, TableEntityRefProps, TableLinkProps, TablePeekProps, TableSidePanelProps, TableToolbarActionProps, TableWindowPanelProps, useMatrxDataTableHost, useMatrxTableRowAlchemy } from './host.js';
6
6
  import { CopyControlProps } from './copy-types.js';
7
7
  export { AgentPayloadInput } from './copy-types.js';
@@ -5907,6 +5907,7 @@ function ColumnHeaderCell({
5907
5907
  onFilterChange,
5908
5908
  selectOptions = [],
5909
5909
  selectSingle = false,
5910
+ selectAllowCustom = false,
5910
5911
  align = "left",
5911
5912
  className,
5912
5913
  compact = false,
@@ -5942,9 +5943,13 @@ function ColumnHeaderCell({
5942
5943
  const filterActive = isColumnFilterActive(filterValue);
5943
5944
  const deferredFilter = filterApplyLabel !== void 0 || filterShowCancel || filterFooterHint !== void 0;
5944
5945
  const [filterOpen, setFilterOpen] = useState14(false);
5946
+ const [pendingNegation, setPendingNegation] = useState14(false);
5945
5947
  const [draftFilter, setDraftFilter] = useState14(filterValue);
5946
5948
  useEffect9(() => {
5947
- if (!filterOpen) setDraftFilter(filterValue);
5949
+ if (!filterOpen) {
5950
+ setDraftFilter(filterValue);
5951
+ setPendingNegation(filterValue?.negated ?? false);
5952
+ }
5948
5953
  }, [filterOpen, filterValue]);
5949
5954
  const applyFilter = () => {
5950
5955
  onFilterChange(draftFilter);
@@ -5956,6 +5961,7 @@ function ColumnHeaderCell({
5956
5961
  };
5957
5962
  const visibleFilter = deferredFilter ? draftFilter : filterValue;
5958
5963
  const setNegated = (negated) => {
5964
+ setPendingNegation(negated);
5959
5965
  if (!visibleFilter) return;
5960
5966
  const next = { ...visibleFilter, ...negated ? { negated: true } : {} };
5961
5967
  if (!negated) delete next.negated;
@@ -6032,12 +6038,13 @@ function ColumnHeaderCell({
6032
6038
  kind: filterKind,
6033
6039
  value: visibleFilter,
6034
6040
  onChange: (next) => {
6035
- const preservingNegation = next && visibleFilter?.negated ? { ...next, negated: true } : next;
6041
+ const preservingNegation = next && (visibleFilter?.negated ?? pendingNegation) ? { ...next, negated: true } : next;
6036
6042
  if (deferredFilter) setDraftFilter(preservingNegation);
6037
6043
  else onFilterChange(preservingNegation);
6038
6044
  },
6039
6045
  selectOptions,
6040
6046
  selectSingle,
6047
+ selectAllowCustom,
6041
6048
  ...markerLabels ? {
6042
6049
  booleanLabels: {
6043
6050
  all: "All",
@@ -6048,18 +6055,18 @@ function ColumnHeaderCell({
6048
6055
  allowNullModes
6049
6056
  }
6050
6057
  ) : null,
6051
- filterKind && visibleFilter && allowNegation ? /* @__PURE__ */ jsxs22("div", { className: "mt-2 border-t border-border pt-2", children: [
6058
+ filterKind && allowNegation ? /* @__PURE__ */ jsxs22("div", { className: "mt-2 border-t border-border pt-2", children: [
6052
6059
  /* @__PURE__ */ jsx31("p", { className: "mb-1 text-[11px] font-medium uppercase tracking-wider text-muted-foreground", children: "Match mode" }),
6053
6060
  /* @__PURE__ */ jsxs22("div", { className: "grid grid-cols-2 gap-1 rounded-md border p-0.5", children: [
6054
6061
  /* @__PURE__ */ jsx31(
6055
6062
  "button",
6056
6063
  {
6057
6064
  type: "button",
6058
- "aria-pressed": !visibleFilter.negated,
6065
+ "aria-pressed": !(visibleFilter?.negated ?? pendingNegation),
6059
6066
  onClick: () => setNegated(false),
6060
6067
  className: cn(
6061
6068
  "rounded px-2 py-1.5 text-xs transition-colors",
6062
- !visibleFilter.negated ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"
6069
+ !(visibleFilter?.negated ?? pendingNegation) ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-muted"
6063
6070
  ),
6064
6071
  children: "Include"
6065
6072
  }
@@ -6068,11 +6075,11 @@ function ColumnHeaderCell({
6068
6075
  "button",
6069
6076
  {
6070
6077
  type: "button",
6071
- "aria-pressed": visibleFilter.negated === true,
6078
+ "aria-pressed": visibleFilter?.negated ?? pendingNegation,
6072
6079
  onClick: () => setNegated(true),
6073
6080
  className: cn(
6074
6081
  "rounded px-2 py-1.5 text-xs transition-colors",
6075
- visibleFilter.negated ? "bg-destructive text-destructive-foreground" : "text-muted-foreground hover:bg-muted"
6082
+ visibleFilter?.negated ?? pendingNegation ? "bg-destructive text-destructive-foreground" : "text-muted-foreground hover:bg-muted"
6076
6083
  ),
6077
6084
  children: "Exclude"
6078
6085
  }
@@ -6260,6 +6267,7 @@ function FilterBody({
6260
6267
  onChange,
6261
6268
  selectOptions,
6262
6269
  selectSingle = false,
6270
+ selectAllowCustom = false,
6263
6271
  allowNullModes = false,
6264
6272
  booleanLabels
6265
6273
  }) {
@@ -6323,15 +6331,29 @@ function FilterBody({
6323
6331
  }
6324
6332
  if (kind === "select") {
6325
6333
  const selected = value?.kind === "select" ? value.values ?? (value.value && value.value !== "__all__" ? [value.value] : []) : [];
6326
- return /* @__PURE__ */ jsx31(
6327
- SearchableSelectFilter,
6328
- {
6329
- selected,
6330
- options: selectOptions,
6331
- onChange,
6332
- single: selectSingle
6333
- }
6334
- );
6334
+ return /* @__PURE__ */ jsxs22("div", { className: "space-y-2", children: [
6335
+ allowNullModes && /* @__PURE__ */ jsx31("div", { className: "flex flex-wrap gap-1", "aria-label": "Blank checks", children: [["empty", "(empty)"], ["not_empty", "(not empty)"], ["null", "(null)"], ["not_null", "(not null)"]].map(([mode, label]) => /* @__PURE__ */ jsx31(
6336
+ "button",
6337
+ {
6338
+ type: "button",
6339
+ "aria-pressed": value?.kind === "text" && value.mode === mode,
6340
+ className: "rounded border px-1.5 py-0.5 text-[10px] hover:bg-muted",
6341
+ onClick: () => onChange({ kind: "text", value: "", mode }),
6342
+ children: label
6343
+ },
6344
+ mode
6345
+ )) }),
6346
+ /* @__PURE__ */ jsx31(
6347
+ SearchableSelectFilter,
6348
+ {
6349
+ selected,
6350
+ options: selectOptions,
6351
+ onChange,
6352
+ single: selectSingle,
6353
+ allowCustom: selectAllowCustom
6354
+ }
6355
+ )
6356
+ ] });
6335
6357
  }
6336
6358
  if (kind === "boolean") {
6337
6359
  const current = value?.kind === "boolean" ? value.value : "__all__";
@@ -6363,7 +6385,8 @@ function SearchableSelectFilter({
6363
6385
  selected,
6364
6386
  options,
6365
6387
  onChange,
6366
- single = false
6388
+ single = false,
6389
+ allowCustom = false
6367
6390
  }) {
6368
6391
  const [query, setQuery] = useState14("");
6369
6392
  const filtered = useMemo5(() => {
@@ -6413,6 +6436,11 @@ function SearchableSelectFilter({
6413
6436
  /* @__PURE__ */ jsxs22(CommandList, { className: "max-h-48", children: [
6414
6437
  /* @__PURE__ */ jsx31(CommandEmpty, { className: "py-3 text-xs text-muted-foreground", children: "No matches" }),
6415
6438
  /* @__PURE__ */ jsxs22(CommandGroup, { children: [
6439
+ allowCustom && query.trim() && !options.some((option) => option.value === query.trim()) && /* @__PURE__ */ jsxs22(CommandItem, { value: `custom:${query.trim()}`, onSelect: () => toggle(query.trim()), className: "text-xs", children: [
6440
+ "Use \u201C",
6441
+ query.trim(),
6442
+ "\u201D"
6443
+ ] }),
6416
6444
  /* @__PURE__ */ jsx31(
6417
6445
  CommandItem,
6418
6446
  {
@@ -8770,6 +8798,7 @@ function MatrxDataTableCore({
8770
8798
  hidePagination = false,
8771
8799
  filterUi,
8772
8800
  detail,
8801
+ expandedDetail,
8773
8802
  window: windowConfig,
8774
8803
  copy,
8775
8804
  contextMenu,
@@ -9637,7 +9666,20 @@ function MatrxDataTableCore({
9637
9666
  setWindowRowId(null);
9638
9667
  setWindowRowSnapshot(null);
9639
9668
  };
9669
+ const canExpandRow = (row) => Boolean(expandedDetail && (expandedDetail.canExpand?.(row) ?? true));
9670
+ const isRowExpanded = (row) => canExpandRow(row) && expandedDetail?.expandedId === getRowId(row);
9671
+ const toggleExpanded = (row) => {
9672
+ if (!expandedDetail || !canExpandRow(row)) return;
9673
+ const id = getRowId(row);
9674
+ expandedDetail.onExpandedIdChange(
9675
+ expandedDetail.expandedId === id ? null : id
9676
+ );
9677
+ };
9640
9678
  const openRow = (row) => {
9679
+ if (canExpandRow(row)) {
9680
+ toggleExpanded(row);
9681
+ return;
9682
+ }
9641
9683
  if (opensWindowOnRowClick) {
9642
9684
  openWindow(row);
9643
9685
  return;
@@ -9741,7 +9783,11 @@ function MatrxDataTableCore({
9741
9783
  } : {},
9742
9784
  ...editEnabled && visibleColumns.some(
9743
9785
  (column) => column.editable && (column.editableIf?.(row) ?? true)
9744
- ) ? { beginEdit: () => beginRowEdit(row) } : {}
9786
+ ) ? { beginEdit: () => beginRowEdit(row) } : {},
9787
+ ...canExpandRow(row) ? {
9788
+ isExpanded: isRowExpanded(row),
9789
+ toggleExpanded: () => toggleExpanded(row)
9790
+ } : {}
9745
9791
  };
9746
9792
  };
9747
9793
  const hierarchyRows = hierarchy?.rows ?? data;
@@ -10647,6 +10693,7 @@ function MatrxDataTableCore({
10647
10693
  ] }) }) : paginated.map((row, index) => {
10648
10694
  const id = getRowId(row);
10649
10695
  const displayRow = applyRowEdits(row, edits[id]);
10696
+ const controls = buildRecordControls(displayRow);
10650
10697
  const selectable = selection?.isRowSelectable?.(row) ?? Boolean(selection);
10651
10698
  return /* @__PURE__ */ jsx41("div", { "data-row-id": id, className: "contents", children: mobileCards(displayRow, index, {
10652
10699
  renderCell: (columnKey) => {
@@ -10681,10 +10728,15 @@ function MatrxDataTableCore({
10681
10728
  ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
10682
10729
  }
10683
10730
  ) : null,
10684
- renderRowActions(displayRow, buildRecordControls(displayRow))
10731
+ renderRowActions(displayRow, controls)
10685
10732
  ]
10686
10733
  }
10687
- ) : null
10734
+ ) : null,
10735
+ ...canExpandRow(row) ? {
10736
+ isExpanded: isRowExpanded(row),
10737
+ toggleExpanded: () => toggleExpanded(row)
10738
+ } : {},
10739
+ expandedDetail: expandedDetail && isRowExpanded(row) ? expandedDetail.render(displayRow, controls) : null
10688
10740
  }) }, id);
10689
10741
  }),
10690
10742
  appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ jsxs31(
@@ -10874,6 +10926,7 @@ function MatrxDataTableCore({
10874
10926
  onFilterChange: (next) => setColumnFilter(id, next),
10875
10927
  selectOptions: meta?.options,
10876
10928
  selectSingle: col.filterSingle,
10929
+ selectAllowCustom: col.filterAllowCustom,
10877
10930
  filterApplyLabel: filterUi?.applyLabel,
10878
10931
  filterShowCancel: filterUi?.showCancel,
10879
10932
  filterFooterHint: filterUi?.footerHint,
@@ -10951,6 +11004,7 @@ function MatrxDataTableCore({
10951
11004
  const isSelected = selectedId === id;
10952
11005
  const rowEdits = edits[id];
10953
11006
  const displayRow = applyRowEdits(row, rowEdits);
11007
+ const controls = buildRecordControls(displayRow);
10954
11008
  const isChecked = selectedIdSet.has(id);
10955
11009
  const rowNode = /* @__PURE__ */ jsxs31(
10956
11010
  "tr",
@@ -10979,7 +11033,7 @@ function MatrxDataTableCore({
10979
11033
  // horizontally. The translucent zebra/hover tints remain
10980
11034
  // desktop-only so densely layered mobile content stays crisp.
10981
11035
  "border-b border-border/60 bg-card transition-colors",
10982
- (detailEnabled || Boolean(onRowOpen)) && "cursor-pointer sm:hover:bg-muted/50",
11036
+ (detailEnabled || Boolean(onRowOpen) || canExpandRow(row)) && "cursor-pointer sm:hover:bg-muted/50",
10983
11037
  isSelected && "bg-muted",
10984
11038
  isChecked && "bg-primary/5",
10985
11039
  highlightedIndex === index && "bg-muted ring-1 ring-inset ring-primary/60",
@@ -11095,7 +11149,7 @@ function MatrxDataTableCore({
11095
11149
  ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
11096
11150
  }
11097
11151
  ) : null,
11098
- renderRowActions(displayRow, buildRecordControls(displayRow)),
11152
+ renderRowActions(displayRow, controls),
11099
11153
  windowEnabled ? /* @__PURE__ */ jsxs31(Tooltip, { children: [
11100
11154
  /* @__PURE__ */ jsx41(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx41(
11101
11155
  Button,
@@ -11126,15 +11180,36 @@ function MatrxDataTableCore({
11126
11180
  id
11127
11181
  );
11128
11182
  const wrappedRow = rowWrapper ? rowWrapper(row, rowNode) : rowNode;
11129
- return hierarchy ? /* @__PURE__ */ jsx41(
11130
- HierarchyDroppableRow,
11183
+ const inlineDetail = expandedDetail && isRowExpanded(row) ? /* @__PURE__ */ jsx41(
11184
+ "tr",
11131
11185
  {
11132
- id,
11133
- disabled: !canDropOn(row),
11134
- children: wrappedRow
11186
+ "data-matrx-table-expanded-detail": id,
11187
+ className: cn("bg-muted/20", expandedDetail.className),
11188
+ children: /* @__PURE__ */ jsx41(
11189
+ "td",
11190
+ {
11191
+ colSpan: visibleColumns.length + leadingCols + (showActionsCol ? 1 : 0),
11192
+ className: "p-4",
11193
+ children: expandedDetail.render(displayRow, controls)
11194
+ }
11195
+ )
11135
11196
  },
11136
- id
11137
- ) : /* @__PURE__ */ jsx41(Fragment6, { children: wrappedRow }, id);
11197
+ `${id}:expanded-detail`
11198
+ ) : null;
11199
+ return hierarchy ? /* @__PURE__ */ jsxs31(Fragment6, { children: [
11200
+ /* @__PURE__ */ jsx41(
11201
+ HierarchyDroppableRow,
11202
+ {
11203
+ id,
11204
+ disabled: !canDropOn(row),
11205
+ children: wrappedRow
11206
+ }
11207
+ ),
11208
+ inlineDetail
11209
+ ] }, id) : /* @__PURE__ */ jsxs31(Fragment6, { children: [
11210
+ wrappedRow,
11211
+ inlineDetail
11212
+ ] }, id);
11138
11213
  }),
11139
11214
  appendQuery !== null && isFetching && !isLoading ? /* @__PURE__ */ jsx41("tr", { "data-matrx-table-append-loading-row": true, children: /* @__PURE__ */ jsx41(
11140
11215
  "td",