@ai-matrx/design-system 0.42.1 → 0.43.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 (35) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/data-table/copy-helpers.d.cts +1 -1
  3. package/dist/data-table/copy-helpers.d.ts +1 -1
  4. package/dist/data-table/filter-engine.d.cts +1 -1
  5. package/dist/data-table/filter-engine.d.ts +1 -1
  6. package/dist/data-table/host.d.cts +1 -1
  7. package/dist/data-table/host.d.ts +1 -1
  8. package/dist/data-table/index.cjs +75 -3
  9. package/dist/data-table/index.cjs.map +1 -1
  10. package/dist/data-table/index.d.cts +2 -2
  11. package/dist/data-table/index.d.ts +2 -2
  12. package/dist/data-table/index.js +75 -3
  13. package/dist/data-table/index.js.map +1 -1
  14. package/dist/data-table/infer-filter.d.cts +1 -1
  15. package/dist/data-table/infer-filter.d.ts +1 -1
  16. package/dist/data-table/layered-filters.d.cts +1 -1
  17. package/dist/data-table/layered-filters.d.ts +1 -1
  18. package/dist/data-table/query-control.d.cts +1 -1
  19. package/dist/data-table/query-control.d.ts +1 -1
  20. package/dist/data-table/spreadsheet.cjs +68 -1
  21. package/dist/data-table/spreadsheet.cjs.map +1 -1
  22. package/dist/data-table/spreadsheet.d.cts +55 -1
  23. package/dist/data-table/spreadsheet.d.ts +55 -1
  24. package/dist/data-table/spreadsheet.js +68 -1
  25. package/dist/data-table/spreadsheet.js.map +1 -1
  26. package/dist/data-table/types.cjs.map +1 -1
  27. package/dist/data-table/types.d.cts +1 -1
  28. package/dist/data-table/types.d.ts +1 -1
  29. package/dist/data-table/url-state.d.cts +1 -1
  30. package/dist/data-table/url-state.d.ts +1 -1
  31. package/dist/data-table/xlsx.d.cts +1 -1
  32. package/dist/data-table/xlsx.d.ts +1 -1
  33. package/dist/{types-afUz93xo.d.ts → types-CUR8Hbt5.d.ts} +12 -0
  34. package/dist/{types-q5ficDSo.d.cts → types-CqU57qk8.d.cts} +12 -0
  35. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.43.0 (2026-09-26 — type-to-edit in spreadsheet mode)
4
+
5
+ * **Type to edit, for every table in spreadsheet mode.** The grid's keyboard focus now lives in a
6
+ hidden TYPE CATCHER textarea inside the scroll container (`[data-matrx-type-catcher]`,
7
+ `inputMode="none"`), so text that never arrives as a one-character keydown — an IME
8
+ composition, an Option / AltGr character, a dead-key accent, dictation, insertText — still opens
9
+ the selected cell's editor seeded with it. A paste or drop into the catcher is never a seed; a
10
+ space alone opens nothing; a `readOnly` grid takes nothing. Grid keys still bubble to the
11
+ container exactly as before (`targetsAnEditor` excludes the catcher). New hook return
12
+ `typeCatcherProps` and `containerProps.onFocus` (Tab into the grid lands in the catcher).
13
+ * **`spreadsheet.onEditRequest(address, seed)`** — a consumer whose cells carry their own editor
14
+ (no `editable` on the column) is asked to open it, with what was typed (`null` for Enter/F2).
15
+ Test: `MatrxDataTable.type-to-edit.test.tsx` (RED 6/6 on 0.42.1 → GREEN 6/6; data-table 667/667).
16
+
3
17
  ## 0.42.1
4
18
  ### Unreleased
5
19
 
@@ -1,5 +1,5 @@
1
1
  import { AgentPayloadInput } from './copy-types.cjs';
2
- import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-q5ficDSo.cjs';
2
+ import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-CqU57qk8.cjs';
3
3
  import '../content-transfer.cjs';
4
4
  import 'react';
5
5
  import '@ai-matrx/kit/content-transfer';
@@ -1,5 +1,5 @@
1
1
  import { AgentPayloadInput } from './copy-types.js';
2
- import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-afUz93xo.js';
2
+ import { g as MatrxDataTableCopyConfig, M as MatrxColumnDef } from '../types-CUR8Hbt5.js';
3
3
  import '../content-transfer.js';
4
4
  import 'react';
5
5
  import '@ai-matrx/kit/content-transfer';
@@ -1,4 +1,4 @@
1
- import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-q5ficDSo.cjs';
1
+ import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-CqU57qk8.cjs';
2
2
  import '../content-transfer.cjs';
3
3
  import 'react';
4
4
  import '@ai-matrx/kit/content-transfer';
@@ -1,4 +1,4 @@
1
- import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-afUz93xo.js';
1
+ import { M as MatrxColumnDef, C as ColumnFiltersState, S as SortState, L as LayeredFilterRule, T as TableSearchMatchMode, a as ColumnFilterValue } from '../types-CUR8Hbt5.js';
2
2
  import '../content-transfer.js';
3
3
  import 'react';
4
4
  import '@ai-matrx/kit/content-transfer';
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { ComponentType, ReactNode, MouseEventHandler } from 'react';
3
3
  import { CopyControlProps } from './copy-types.cjs';
4
4
  export { AgentPayloadInput, AiCustomSource, AiVariant, CopyExportConfig } from './copy-types.cjs';
5
- import { b as TableSavedViewsProps, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-q5ficDSo.cjs';
5
+ import { b as TableSavedViewsProps, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-CqU57qk8.cjs';
6
6
  import { MatrxTableMenuTarget, MatrxTableMenuPayload, MatrxTableMenuSectionsResolver, MatrxTableMenuIconName } from './menu-targets.cjs';
7
7
  export { MatrxTableMenuItem, MatrxTableMenuSection } from './menu-targets.cjs';
8
8
  import '../content-transfer.cjs';
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import { ComponentType, ReactNode, MouseEventHandler } from 'react';
3
3
  import { CopyControlProps } from './copy-types.js';
4
4
  export { AgentPayloadInput, AiCustomSource, AiVariant, CopyExportConfig } from './copy-types.js';
5
- import { b as TableSavedViewsProps, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-afUz93xo.js';
5
+ import { b as TableSavedViewsProps, c as MatrxDataTableDensity, d as MatrxDataTableRecordControls } from '../types-CUR8Hbt5.js';
6
6
  import { MatrxTableMenuTarget, MatrxTableMenuPayload, MatrxTableMenuSectionsResolver, MatrxTableMenuIconName } from './menu-targets.js';
7
7
  export { MatrxTableMenuItem, MatrxTableMenuSection } from './menu-targets.js';
8
8
  import '../content-transfer.js';
@@ -8608,8 +8608,23 @@ function canRedo(stack) {
8608
8608
  function targetsAnEditor(target) {
8609
8609
  const element = target instanceof Element ? target : null;
8610
8610
  if (!element) return false;
8611
+ if (element.closest(`[${TYPE_CATCHER_ATTR}]`)) return false;
8611
8612
  return element.closest("input, textarea, select, [contenteditable='true']") !== null;
8612
8613
  }
8614
+ var TYPE_CATCHER_ATTR = "data-matrx-type-catcher";
8615
+ var TYPE_CATCHER_STYLE = {
8616
+ position: "fixed",
8617
+ top: 0,
8618
+ left: 0,
8619
+ width: 1,
8620
+ height: 1,
8621
+ padding: 0,
8622
+ border: 0,
8623
+ opacity: 0,
8624
+ overflow: "hidden",
8625
+ resize: "none",
8626
+ pointerEvents: "none"
8627
+ };
8613
8628
  function camePastAPortal(target, host) {
8614
8629
  if (typeof Element === "undefined") return false;
8615
8630
  const element = target instanceof Element ? target : null;
@@ -8629,6 +8644,8 @@ function useSpreadsheetGrid(options) {
8629
8644
  const [fillTarget, setFillTarget] = (0, import_react15.useState)(null);
8630
8645
  const [stack, setStack] = (0, import_react15.useState)(() => createUndoStack(options?.undoDepth ?? 100));
8631
8646
  const draggingRef = (0, import_react15.useRef)(null);
8647
+ const catcherRef = (0, import_react15.useRef)(null);
8648
+ const composingRef = (0, import_react15.useRef)(false);
8632
8649
  const optionsRef = (0, import_react15.useRef)(options);
8633
8650
  optionsRef.current = options;
8634
8651
  const rowIds = options?.rowIds ?? [];
@@ -9007,7 +9024,9 @@ function useSpreadsheetGrid(options) {
9007
9024
  event.preventDefault();
9008
9025
  const origin = event.currentTarget;
9009
9026
  if (typeof HTMLElement !== "undefined" && origin instanceof HTMLElement) {
9010
- origin.closest('[data-matrx-table-spreadsheet="true"]')?.focus({ preventScroll: true });
9027
+ const container = origin.closest('[data-matrx-table-spreadsheet="true"]');
9028
+ const catcher = container?.querySelector(`[${TYPE_CATCHER_ATTR}]`);
9029
+ (catcher ?? container)?.focus({ preventScroll: true });
9011
9030
  }
9012
9031
  setRange(
9013
9032
  (previous) => event.shiftKey && previous ? { anchor: previous.anchor, focus: address } : { anchor: address, focus: address }
@@ -9078,11 +9097,58 @@ function useSpreadsheetGrid(options) {
9078
9097
  window.addEventListener("mouseup", commit);
9079
9098
  return () => window.removeEventListener("mouseup", commit);
9080
9099
  }, [options, fillRequestBase, applyPatches, announceSkips, screenPatches, refuseWrite]);
9100
+ const takeTypedText = (0, import_react15.useCallback)(
9101
+ (text) => {
9102
+ if (catcherRef.current) catcherRef.current.value = "";
9103
+ const current = optionsRef.current;
9104
+ const focused = range?.focus;
9105
+ if (!current || !focused || current.readOnly || !current.onEditRequest) return;
9106
+ if (text.trim() === "") return;
9107
+ current.onEditRequest(focused, text);
9108
+ },
9109
+ [range]
9110
+ );
9111
+ const typeCatcherProps = {
9112
+ ref: (element) => {
9113
+ catcherRef.current = element;
9114
+ },
9115
+ tabIndex: -1,
9116
+ "aria-label": "Type to edit the selected cell",
9117
+ inputMode: "none",
9118
+ autoComplete: "off",
9119
+ autoCorrect: "off",
9120
+ autoCapitalize: "off",
9121
+ spellCheck: false,
9122
+ rows: 1,
9123
+ [TYPE_CATCHER_ATTR]: "",
9124
+ style: TYPE_CATCHER_STYLE,
9125
+ onInput: (event) => {
9126
+ const kind = event.nativeEvent?.inputType;
9127
+ if (typeof kind === "string" && (kind.startsWith("insertFromPaste") || kind.startsWith("insertFromDrop"))) {
9128
+ event.currentTarget.value = "";
9129
+ return;
9130
+ }
9131
+ if (composingRef.current) return;
9132
+ takeTypedText(event.currentTarget.value);
9133
+ },
9134
+ onCompositionStart: () => {
9135
+ composingRef.current = true;
9136
+ },
9137
+ onCompositionEnd: (event) => {
9138
+ composingRef.current = false;
9139
+ takeTypedText(event.data || event.currentTarget.value);
9140
+ }
9141
+ };
9081
9142
  return {
9082
9143
  range,
9083
9144
  bounds,
9084
9145
  enabled: options !== null,
9146
+ typeCatcherProps,
9085
9147
  containerProps: {
9148
+ onFocus: (event) => {
9149
+ if (event.target !== event.currentTarget) return;
9150
+ catcherRef.current?.focus({ preventScroll: true });
9151
+ },
9086
9152
  tabIndex: options ? 0 : -1,
9087
9153
  onKeyDown,
9088
9154
  onCopy,
@@ -14069,13 +14135,17 @@ function MatrxDataTableCore({
14069
14135
  }));
14070
14136
  };
14071
14137
  const requestCellEdit = (address, seed) => {
14072
- if (!editEnabled) return false;
14138
+ if (!editEnabled && !spreadsheet?.onEditRequest) return false;
14073
14139
  const row = data.find((candidate) => getRowId(candidate) === address.rowId);
14074
14140
  if (!row) return false;
14075
14141
  const column = visibleColumns.find(
14076
14142
  (candidate) => columnId(candidate) === address.fieldName
14077
14143
  );
14078
- if (!column?.editable || !(column.editableIf?.(row) ?? true)) return false;
14144
+ if (!column?.editable) {
14145
+ const own = spreadsheet?.onEditRequest;
14146
+ return own ? own({ rowId: address.rowId, columnId: address.fieldName }, seed) : false;
14147
+ }
14148
+ if (!(column.editableIf?.(row) ?? true)) return false;
14079
14149
  const field = column.accessorKey ? String(column.accessorKey) : columnId(column);
14080
14150
  setEditRequest((current) => ({
14081
14151
  rowId: address.rowId,
@@ -15204,6 +15274,7 @@ function MatrxDataTableCore({
15204
15274
  onCopy: sheet.containerProps.onCopy,
15205
15275
  onCut: sheet.containerProps.onCut,
15206
15276
  onPaste: sheet.containerProps.onPaste,
15277
+ onFocus: sheet.containerProps.onFocus,
15207
15278
  "data-matrx-table-spreadsheet": "true"
15208
15279
  } : {},
15209
15280
  "aria-busy": isLoading || isFetching,
@@ -15214,6 +15285,7 @@ function MatrxDataTableCore({
15214
15285
  tableClassName
15215
15286
  ),
15216
15287
  children: [
15288
+ spreadsheetEnabled ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("textarea", { ...sheet.typeCatcherProps }) : null,
15217
15289
  hierarchy && draggedRow ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
15218
15290
  HierarchyRootDropTarget,
15219
15291
  {