@nokecy/qc-ui 1.1.38 → 1.1.39

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 (121) hide show
  1. package/dist/cjs/ag-grid-plus/ag-gridPlus.js +33 -20
  2. package/dist/cjs/ag-grid-plus/context/useSchemeDataFlow.js +37 -1
  3. package/dist/cjs/ag-grid-plus/context/useSchemeManager.js +120 -79
  4. package/dist/cjs/ag-grid-plus/setting/ColumnSetting.js +52 -36
  5. package/dist/cjs/ag-grid-plus/setting/columnGroupUtils.js +14 -3
  6. package/dist/cjs/array-table/arrayAddBtn.js +26 -17
  7. package/dist/cjs/array-table/hooks.d.ts +2 -1
  8. package/dist/cjs/array-table/hooks.js +23 -43
  9. package/dist/cjs/array-table/index.js +105 -25
  10. package/dist/cjs/array-table/preview.js +1 -1
  11. package/dist/cjs/array-table/readOnlyFormatters.d.ts +28 -0
  12. package/dist/cjs/array-table/readOnlyFormatters.js +113 -0
  13. package/dist/cjs/array-table/utils.d.ts +2 -2
  14. package/dist/cjs/array-table/utils.js +162 -11
  15. package/dist/cjs/editable/index.js +3 -1
  16. package/dist/cjs/formDesigner/FormDesigner.js +3 -2
  17. package/dist/cjs/formDesigner/preWidgets/index.d.ts +1 -10
  18. package/dist/cjs/formDesigner/preWidgets/index.js +1 -100
  19. package/dist/cjs/formDesigner/preWidgets/preDefineProperty.d.ts +11 -0
  20. package/dist/cjs/formDesigner/preWidgets/preDefineProperty.js +70 -0
  21. package/dist/esm/ag-grid-plus/ag-gridPlus.js +33 -20
  22. package/dist/esm/ag-grid-plus/context/useSchemeDataFlow.js +37 -1
  23. package/dist/esm/ag-grid-plus/context/useSchemeManager.js +120 -79
  24. package/dist/esm/ag-grid-plus/setting/ColumnSetting.js +52 -36
  25. package/dist/esm/ag-grid-plus/setting/columnGroupUtils.js +13 -0
  26. package/dist/esm/array-table/arrayAddBtn.js +26 -17
  27. package/dist/esm/array-table/hooks.d.ts +2 -1
  28. package/dist/esm/array-table/hooks.js +23 -43
  29. package/dist/esm/array-table/index.js +107 -27
  30. package/dist/esm/array-table/preview.js +2 -2
  31. package/dist/esm/array-table/readOnlyFormatters.d.ts +28 -0
  32. package/dist/esm/array-table/readOnlyFormatters.js +107 -0
  33. package/dist/esm/array-table/utils.d.ts +2 -2
  34. package/dist/esm/array-table/utils.js +162 -11
  35. package/dist/esm/editable/index.js +3 -1
  36. package/dist/esm/formDesigner/FormDesigner.js +3 -2
  37. package/dist/esm/formDesigner/preWidgets/index.d.ts +1 -10
  38. package/dist/esm/formDesigner/preWidgets/index.js +1 -10
  39. package/dist/esm/formDesigner/preWidgets/preDefineProperty.d.ts +11 -0
  40. package/dist/esm/formDesigner/preWidgets/{preDefineProperty1/preview.js → preDefineProperty.js} +49 -30
  41. package/dist/umd/qc-ui.min.js +1 -1
  42. package/package.json +1 -1
  43. package/dist/cjs/formDesigner/preWidgets/preDefineProperty1/index.d.ts +0 -1
  44. package/dist/cjs/formDesigner/preWidgets/preDefineProperty1/index.js +0 -16
  45. package/dist/cjs/formDesigner/preWidgets/preDefineProperty1/preview.d.ts +0 -5
  46. package/dist/cjs/formDesigner/preWidgets/preDefineProperty1/preview.js +0 -51
  47. package/dist/cjs/formDesigner/preWidgets/preDefineProperty10/index.d.ts +0 -1
  48. package/dist/cjs/formDesigner/preWidgets/preDefineProperty10/index.js +0 -16
  49. package/dist/cjs/formDesigner/preWidgets/preDefineProperty10/preview.d.ts +0 -5
  50. package/dist/cjs/formDesigner/preWidgets/preDefineProperty10/preview.js +0 -50
  51. package/dist/cjs/formDesigner/preWidgets/preDefineProperty2/index.d.ts +0 -1
  52. package/dist/cjs/formDesigner/preWidgets/preDefineProperty2/index.js +0 -16
  53. package/dist/cjs/formDesigner/preWidgets/preDefineProperty2/preview.d.ts +0 -5
  54. package/dist/cjs/formDesigner/preWidgets/preDefineProperty2/preview.js +0 -50
  55. package/dist/cjs/formDesigner/preWidgets/preDefineProperty3/index.d.ts +0 -1
  56. package/dist/cjs/formDesigner/preWidgets/preDefineProperty3/index.js +0 -16
  57. package/dist/cjs/formDesigner/preWidgets/preDefineProperty3/preview.d.ts +0 -5
  58. package/dist/cjs/formDesigner/preWidgets/preDefineProperty3/preview.js +0 -50
  59. package/dist/cjs/formDesigner/preWidgets/preDefineProperty4/index.d.ts +0 -1
  60. package/dist/cjs/formDesigner/preWidgets/preDefineProperty4/index.js +0 -16
  61. package/dist/cjs/formDesigner/preWidgets/preDefineProperty4/preview.d.ts +0 -5
  62. package/dist/cjs/formDesigner/preWidgets/preDefineProperty4/preview.js +0 -50
  63. package/dist/cjs/formDesigner/preWidgets/preDefineProperty5/index.d.ts +0 -1
  64. package/dist/cjs/formDesigner/preWidgets/preDefineProperty5/index.js +0 -16
  65. package/dist/cjs/formDesigner/preWidgets/preDefineProperty5/preview.d.ts +0 -5
  66. package/dist/cjs/formDesigner/preWidgets/preDefineProperty5/preview.js +0 -50
  67. package/dist/cjs/formDesigner/preWidgets/preDefineProperty6/index.d.ts +0 -1
  68. package/dist/cjs/formDesigner/preWidgets/preDefineProperty6/index.js +0 -16
  69. package/dist/cjs/formDesigner/preWidgets/preDefineProperty6/preview.d.ts +0 -5
  70. package/dist/cjs/formDesigner/preWidgets/preDefineProperty6/preview.js +0 -50
  71. package/dist/cjs/formDesigner/preWidgets/preDefineProperty7/index.d.ts +0 -1
  72. package/dist/cjs/formDesigner/preWidgets/preDefineProperty7/index.js +0 -16
  73. package/dist/cjs/formDesigner/preWidgets/preDefineProperty7/preview.d.ts +0 -5
  74. package/dist/cjs/formDesigner/preWidgets/preDefineProperty7/preview.js +0 -50
  75. package/dist/cjs/formDesigner/preWidgets/preDefineProperty8/index.d.ts +0 -1
  76. package/dist/cjs/formDesigner/preWidgets/preDefineProperty8/index.js +0 -16
  77. package/dist/cjs/formDesigner/preWidgets/preDefineProperty8/preview.d.ts +0 -5
  78. package/dist/cjs/formDesigner/preWidgets/preDefineProperty8/preview.js +0 -50
  79. package/dist/cjs/formDesigner/preWidgets/preDefineProperty9/index.d.ts +0 -1
  80. package/dist/cjs/formDesigner/preWidgets/preDefineProperty9/index.js +0 -16
  81. package/dist/cjs/formDesigner/preWidgets/preDefineProperty9/preview.d.ts +0 -5
  82. package/dist/cjs/formDesigner/preWidgets/preDefineProperty9/preview.js +0 -50
  83. package/dist/esm/formDesigner/preWidgets/preDefineProperty1/index.d.ts +0 -1
  84. package/dist/esm/formDesigner/preWidgets/preDefineProperty1/index.js +0 -1
  85. package/dist/esm/formDesigner/preWidgets/preDefineProperty1/preview.d.ts +0 -5
  86. package/dist/esm/formDesigner/preWidgets/preDefineProperty10/index.d.ts +0 -1
  87. package/dist/esm/formDesigner/preWidgets/preDefineProperty10/index.js +0 -1
  88. package/dist/esm/formDesigner/preWidgets/preDefineProperty10/preview.d.ts +0 -5
  89. package/dist/esm/formDesigner/preWidgets/preDefineProperty10/preview.js +0 -43
  90. package/dist/esm/formDesigner/preWidgets/preDefineProperty2/index.d.ts +0 -1
  91. package/dist/esm/formDesigner/preWidgets/preDefineProperty2/index.js +0 -1
  92. package/dist/esm/formDesigner/preWidgets/preDefineProperty2/preview.d.ts +0 -5
  93. package/dist/esm/formDesigner/preWidgets/preDefineProperty2/preview.js +0 -43
  94. package/dist/esm/formDesigner/preWidgets/preDefineProperty3/index.d.ts +0 -1
  95. package/dist/esm/formDesigner/preWidgets/preDefineProperty3/index.js +0 -1
  96. package/dist/esm/formDesigner/preWidgets/preDefineProperty3/preview.d.ts +0 -5
  97. package/dist/esm/formDesigner/preWidgets/preDefineProperty3/preview.js +0 -43
  98. package/dist/esm/formDesigner/preWidgets/preDefineProperty4/index.d.ts +0 -1
  99. package/dist/esm/formDesigner/preWidgets/preDefineProperty4/index.js +0 -1
  100. package/dist/esm/formDesigner/preWidgets/preDefineProperty4/preview.d.ts +0 -5
  101. package/dist/esm/formDesigner/preWidgets/preDefineProperty4/preview.js +0 -43
  102. package/dist/esm/formDesigner/preWidgets/preDefineProperty5/index.d.ts +0 -1
  103. package/dist/esm/formDesigner/preWidgets/preDefineProperty5/index.js +0 -1
  104. package/dist/esm/formDesigner/preWidgets/preDefineProperty5/preview.d.ts +0 -5
  105. package/dist/esm/formDesigner/preWidgets/preDefineProperty5/preview.js +0 -43
  106. package/dist/esm/formDesigner/preWidgets/preDefineProperty6/index.d.ts +0 -1
  107. package/dist/esm/formDesigner/preWidgets/preDefineProperty6/index.js +0 -1
  108. package/dist/esm/formDesigner/preWidgets/preDefineProperty6/preview.d.ts +0 -5
  109. package/dist/esm/formDesigner/preWidgets/preDefineProperty6/preview.js +0 -43
  110. package/dist/esm/formDesigner/preWidgets/preDefineProperty7/index.d.ts +0 -1
  111. package/dist/esm/formDesigner/preWidgets/preDefineProperty7/index.js +0 -1
  112. package/dist/esm/formDesigner/preWidgets/preDefineProperty7/preview.d.ts +0 -5
  113. package/dist/esm/formDesigner/preWidgets/preDefineProperty7/preview.js +0 -43
  114. package/dist/esm/formDesigner/preWidgets/preDefineProperty8/index.d.ts +0 -1
  115. package/dist/esm/formDesigner/preWidgets/preDefineProperty8/index.js +0 -1
  116. package/dist/esm/formDesigner/preWidgets/preDefineProperty8/preview.d.ts +0 -5
  117. package/dist/esm/formDesigner/preWidgets/preDefineProperty8/preview.js +0 -43
  118. package/dist/esm/formDesigner/preWidgets/preDefineProperty9/index.d.ts +0 -1
  119. package/dist/esm/formDesigner/preWidgets/preDefineProperty9/index.js +0 -1
  120. package/dist/esm/formDesigner/preWidgets/preDefineProperty9/preview.d.ts +0 -5
  121. package/dist/esm/formDesigner/preWidgets/preDefineProperty9/preview.js +0 -43
@@ -22,20 +22,32 @@ var _agGridPlus = require("../ag-grid-plus");
22
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
23
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
24
24
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
25
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
25
26
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
26
27
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
27
28
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
28
29
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
29
30
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
30
- function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
31
31
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
32
32
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
33
33
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
34
34
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
35
35
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
36
36
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } // 导入 AG-Grid v33 主题
37
+ // array-table 派生主题:去掉单元格聚焦/选区视觉(行内编辑更干净)。
38
+ // focusShadow -> 聚焦光环
39
+ // rangeSelectionBorder -> 单格点击形成的 1×1 选区蓝边
40
+ // rangeSelectionBackground -> 选区淡蓝填充
41
+ // 仅去视觉,不动焦点功能——键盘导航/点击进编辑仍依赖 cell focus。共用主题不受影响。@author nokecy
42
+ var arrayTableTheme = _theme.agGridTheme.withParams({
43
+ focusShadow: 'none',
44
+ rangeSelectionBorderColor: 'transparent',
45
+ rangeSelectionBackgroundColor: 'transparent'
46
+ });
47
+
37
48
  //@ts-ignore
38
49
  var ArrayTableInner = (0, _react2.observer)(function (props) {
50
+ var _addition$props;
39
51
  var height = props.height,
40
52
  gridKey = props.gridKey;
41
53
 
@@ -49,6 +61,10 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
49
61
  isAdd = _useState2[0],
50
62
  setIsAdd = _useState2[1];
51
63
  var apiRef = (0, _react.useRef)();
64
+ // 懒挂载激活态:存放已激活(点击/导航进过)的单元格 key(`rowId:colId`),供 LazyAgField 经 context 读取。@author nokecy
65
+ var activeCellsRef = (0, _react.useRef)(new Set());
66
+ // 无 _id/id 的外部数据按对象引用分配稳定 rowId(避免 getRowId 返回 undefined)。@author nokecy
67
+ var rowIdMapRef = (0, _react.useRef)(new WeakMap());
52
68
  var ref = (0, _react.useRef)();
53
69
  var field = (0, _react2.useField)();
54
70
  var _useState3 = (0, _react.useState)(undefined),
@@ -66,10 +82,14 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
66
82
  // 通过 JSON.stringify 比较内容,只有内容真正变化时才返回新引用
67
83
  var sourcesKey = (0, _react.useMemo)(function () {
68
84
  return JSON.stringify(rawSources.map(function (s) {
85
+ var _s$columnProps$header, _s$columnProps, _s$columnProps2;
69
86
  return {
70
87
  name: s.name,
71
- display: s.display
72
- // 只提取稳定的标识信息
88
+ display: s.display,
89
+ // 列标题可由 reactions 运行时改写,纳入 key 才能让 stableColumnDefs 跟着重建。
90
+ // 宽度/隐藏/固定由 applyColumnState(方案)管,故意不纳入,避免行编辑时列状态被重置。
91
+ // 可编辑性:带 x-reactions 的列在 buildArrayTableColumns 里已强制走 AgField 全树(尊重运行时 pattern),无需进 key。@author nokecy
92
+ headerName: (_s$columnProps$header = (_s$columnProps = s.columnProps) === null || _s$columnProps === void 0 ? void 0 : _s$columnProps.headerName) !== null && _s$columnProps$header !== void 0 ? _s$columnProps$header : (_s$columnProps2 = s.columnProps) === null || _s$columnProps2 === void 0 ? void 0 : _s$columnProps2.title
73
93
  };
74
94
  }));
75
95
  }, [rawSources]);
@@ -87,8 +107,6 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
87
107
  // 使用自定义 hooks
88
108
  var _useCellFocus = (0, _hooks.useCellFocus)(),
89
109
  focusInputInCell = _useCellFocus.focusInputInCell;
90
- var _useKeyboardNavigatio = (0, _hooks.useKeyboardNavigation)(ref, dataSource, focusInputInCell),
91
- handleCellKeyDown = _useKeyboardNavigatio.handleCellKeyDown;
92
110
  var _useRowDrag = (0, _hooks.useRowDrag)(field),
93
111
  handleRowDragMove = _useRowDrag.handleRowDragMove;
94
112
 
@@ -123,7 +141,7 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
123
141
  */
124
142
  var stableColumnDefs = (0, _react.useMemo)(function () {
125
143
  // 只依赖 sources,不依赖 dataSource 和 field.value
126
- var cols = (0, _utils.useArrayTableColumns)([], field, sources);
144
+ var cols = (0, _utils.buildArrayTableColumns)([], field, sources);
127
145
  //@ts-ignore
128
146
  if (cols.length > 0 && props.onRowDrag) {
129
147
  //@ts-ignore
@@ -132,6 +150,47 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
132
150
  return cols;
133
151
  }, [sources, props.onRowDrag]); // 移除 field 依赖,避免数据变化时重新计算
134
152
 
153
+ // 懒挂载:把激活态 Set 通过 AG-Grid context 暴露给 LazyAgField(引用稳定,原地 mutate)。@author nokecy
154
+ var gridContext = (0, _react.useMemo)(function () {
155
+ return {
156
+ activeCells: activeCellsRef.current
157
+ };
158
+ }, []);
159
+
160
+ // 走懒挂载渲染器的列 id 集合(供点击/键盘导航判断是否需要激活)。@author nokecy
161
+ var lazyColIds = (0, _react.useMemo)(function () {
162
+ return new Set(stableColumnDefs.filter(function (c) {
163
+ var _c$cellRendererParams;
164
+ return c === null || c === void 0 || (_c$cellRendererParams = c.cellRendererParams) === null || _c$cellRendererParams === void 0 ? void 0 : _c$cellRendererParams.lazyEditable;
165
+ }).map(function (c) {
166
+ return c.field;
167
+ }));
168
+ }, [stableColumnDefs]);
169
+
170
+ /**
171
+ * 激活某个懒挂载单元格:加入激活集合并强制重渲该格 -> LazyAgField 改挂 AgField 全树。
172
+ * 返回 true 表示「本次新激活」(调用方需等挂载完成再聚焦);false 表示无需激活(非懒列/新增行/已激活)。@author nokecy
173
+ */
174
+ var activateCell = (0, _react.useCallback)(function (api, node, colId) {
175
+ var _node$data;
176
+ if (!api || !node || !colId) return false;
177
+ if (!lazyColIds.has(colId)) return false; // 非懒列(已是 AgField/纯文本)
178
+ if ((_node$data = node.data) !== null && _node$data !== void 0 && _node$data._isNew) return false; // 新增行本就 eager 挂着
179
+ var key = "".concat(node.id, ":").concat(colId);
180
+ if (activeCellsRef.current.has(key)) return false; // 已激活
181
+ activeCellsRef.current.add(key);
182
+ api.refreshCells({
183
+ rowNodes: [node],
184
+ columns: [colId],
185
+ force: true
186
+ });
187
+ return true;
188
+ }, [lazyColIds]);
189
+
190
+ // 键盘导航 hook 需要 activateCell(导航进懒列时先挂载再聚焦),故置于其后。@author nokecy
191
+ var _useKeyboardNavigatio = (0, _hooks.useKeyboardNavigation)(ref, dataSource, focusInputInCell, activateCell),
192
+ handleCellKeyDown = _useKeyboardNavigatio.handleCellKeyDown;
193
+
135
194
  /**
136
195
  * 方案自动加载
137
196
  *
@@ -165,7 +224,9 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
165
224
 
166
225
  // 如果包含分组,先更新 columnDefs
167
226
  if (hasGroups) {
168
- var gridColumnDefs = (0, _columnGroupUtils.flatConfigToGridState)(currentScheme.columnConfig);
227
+ // 传入 stableColumnDefs 作为原始定义,保留 cellRenderer(AgField/LazyAgField)及其
228
+ // cellRendererParams——否则分组方案重建出的是裸列,单元格退化为纯文本、编辑失效。@author nokecy
229
+ var gridColumnDefs = (0, _columnGroupUtils.flatConfigToGridState)(currentScheme.columnConfig, stableColumnDefs);
169
230
  gridApiState.setGridOption('columnDefs', gridColumnDefs);
170
231
  }
171
232
 
@@ -239,17 +300,20 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
239
300
  marginBottom: 5
240
301
  }
241
302
  }, addition ? /*#__PURE__*/_react.default.createElement(_arrayAddBtn.default, _extends({
242
- arrayField: field,
243
- schema: schema,
244
- defaultValue: {
245
- _id: (0, _uniqueId.default)(),
246
- _isNew: true
247
- },
248
303
  title: "新增",
249
304
  onAdd: function onAdd() {
250
305
  setIsAdd(true);
251
306
  }
252
- }, addition.props)) : null, actions.map(function (column, key) {
307
+ }, addition.props, {
308
+ // 框架关键属性钉在 spread 之后:不可被 addition.props 覆盖;
309
+ // defaultValue 合并自定义字段但始终携带 _id/_isNew 标记。@author nokecy
310
+ arrayField: field,
311
+ schema: schema,
312
+ defaultValue: _objectSpread({
313
+ _id: (0, _uniqueId.default)(),
314
+ _isNew: true
315
+ }, ((_addition$props = addition.props) === null || _addition$props === void 0 ? void 0 : _addition$props.defaultValue) || {})
316
+ })) : null, actions.map(function (column, key) {
253
317
  return /*#__PURE__*/_react.default.createElement(_react2.RecursionField, {
254
318
  schema: column.schema,
255
319
  name: key,
@@ -267,7 +331,8 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
267
331
  minHeight: 0
268
332
  }
269
333
  }, /*#__PURE__*/_react.default.createElement(_agGridReact.AgGridReact, {
270
- theme: _theme.agGridTheme,
334
+ theme: arrayTableTheme,
335
+ context: gridContext,
271
336
  onGridReady: function onGridReady(params) {
272
337
  params.api.hidePopupMenu();
273
338
  apiRef.current = params.api;
@@ -287,15 +352,20 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
287
352
  },
288
353
  onCellKeyDown: handleCellKeyDown,
289
354
  onCellClicked: function onCellClicked(event) {
290
- var _event$event;
291
- // 点击单元格时触发编辑状态
292
- var cellElement = (_event$event = event.event) === null || _event$event === void 0 ? void 0 : _event$event.target;
293
- setTimeout(function () {
294
- var gridCell = cellElement === null || cellElement === void 0 ? void 0 : cellElement.closest('[data-ag-grid-cell]');
295
- if (gridCell) {
296
- focusInputInCell(gridCell);
297
- }
298
- }, 10);
355
+ var _event$colDef;
356
+ // 懒挂载:点击懒列存量格时先激活挂树,等挂载完成再聚焦进编辑;否则沿用原即时聚焦。@author nokecy
357
+ var node = event.node;
358
+ var colId = (_event$colDef = event.colDef) === null || _event$colDef === void 0 ? void 0 : _event$colDef.field;
359
+ var justActivated = activateCell(event.api, node, colId);
360
+ var rowIndex = node === null || node === void 0 ? void 0 : node.rowIndex;
361
+ var focus = function focus() {
362
+ var _ref$current, _event$event;
363
+ // 行虚拟化下 DOM 顺序与 rowIndex 不一致,按 row-index + col-id 属性精确定位刚渲染的格 @author nokecy
364
+ var gridCell = justActivated && rowIndex != null ? (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.querySelector(".ag-row[row-index=\"".concat(rowIndex, "\"] .ag-cell[col-id=\"").concat(colId, "\"]")) : (_event$event = event.event) === null || _event$event === void 0 || (_event$event = _event$event.target) === null || _event$event === void 0 ? void 0 : _event$event.closest('.ag-cell');
365
+ if (gridCell) focusInputInCell(gridCell);
366
+ };
367
+ // 新激活需等 AgField(RecursionField/Editable) 挂载完成,给足时间;否则原 10ms。@author nokecy
368
+ setTimeout(focus, justActivated ? 80 : 10);
299
369
  },
300
370
  onRowDragMove: handleRowDragMove,
301
371
  onRowDataUpdated: function onRowDataUpdated(e) {
@@ -322,8 +392,18 @@ var ArrayTableInner = (0, _react2.observer)(function (props) {
322
392
  }
323
393
  },
324
394
  getRowId: function getRowId(_ref) {
395
+ var _data$_id;
325
396
  var data = _ref.data;
326
- return data._id || data.id;
397
+ var id = (_data$_id = data === null || data === void 0 ? void 0 : data._id) !== null && _data$_id !== void 0 ? _data$_id : data === null || data === void 0 ? void 0 : data.id;
398
+ if (id != null) return String(id);
399
+ // 既无 _id 也无 id 的外部数据:按对象引用从 WeakMap 取/分配稳定 id。
400
+ // 不能用 uniqueId 直返(每次调用都变会让 AG-Grid 行身份错乱),也不能改写 data(触发 Formily 反应)。@author nokecy
401
+ var gen = rowIdMapRef.current.get(data);
402
+ if (!gen) {
403
+ gen = (0, _uniqueId.default)('row_');
404
+ rowIdMapRef.current.set(data, gen);
405
+ }
406
+ return gen;
327
407
  }
328
408
  // rowDragEntireRow={true}
329
409
  // onRowDragEnd={(event) => {
@@ -15,7 +15,7 @@ var ArrayTable = function ArrayTable(props) {
15
15
  var field = (0, _react2.useField)();
16
16
  var dataSource = Array.isArray(field.value) ? field.value.slice() : [];
17
17
  var sources = (0, _utils.useArrayTableSources)();
18
- var columns = (0, _utils.useArrayTableColumns)(dataSource, field, sources);
18
+ var columns = (0, _utils.buildArrayTableColumns)(dataSource, field, sources);
19
19
  return /*#__PURE__*/_react.default.createElement("div", {
20
20
  style: {
21
21
  height: height ? height : 400
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 只读列「纯文本快路径」格式化器注册表
3
+ *
4
+ * 背景:ArrayTable 每个可见单元格默认挂一棵完整 Formily 字段树(AgField),
5
+ * 行虚拟化滚动时整行销毁重建,列多必然掉帧。只读列没有编辑/校验/写回,
6
+ * 完全可以不挂 Formily 树、改用 AG-Grid 的 valueFormatter 出纯文本。
7
+ *
8
+ * 本注册表负责「内层组件类型 -> 显示文本」的映射。命中返回格式化器,
9
+ * 未命中返回 null —— 调用方据此安全回退 AgField(正确优先于速度)。
10
+ *
11
+ * 取舍:这是 Formily readPretty 之外的一份精简显示逻辑,可能与定制 readPretty
12
+ * 发散。靠「未命中即回退 + 消费方可 registerReadOnlyFormatter 扩展」控制风险。
13
+ *
14
+ * @author nokecy
15
+ */
16
+ export type ReadOnlyFormatterCtx = {
17
+ /** 列的 x-component-props(headerName/width/options/format 等) */
18
+ columnProps: any;
19
+ /** 内层数据字段的 schema(可读 enum / x-component-props) */
20
+ fieldSchema: any;
21
+ };
22
+ export type ReadOnlyFormatter = (value: any, ctx: ReadOnlyFormatterCtx) => string;
23
+ /** 消费方扩展自定义只读列的显示逻辑 */
24
+ export declare const registerReadOnlyFormatter: (component: string, formatter: ReadOnlyFormatter) => void;
25
+ /**
26
+ * 取某组件类型的只读格式化器。命中返回函数,未命中返回 null(调用方回退 AgField)。
27
+ */
28
+ export declare const getReadOnlyFormatter: (component: string | undefined) => ReadOnlyFormatter | null;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.registerReadOnlyFormatter = exports.getReadOnlyFormatter = void 0;
7
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
8
+ /**
9
+ * 只读列「纯文本快路径」格式化器注册表
10
+ *
11
+ * 背景:ArrayTable 每个可见单元格默认挂一棵完整 Formily 字段树(AgField),
12
+ * 行虚拟化滚动时整行销毁重建,列多必然掉帧。只读列没有编辑/校验/写回,
13
+ * 完全可以不挂 Formily 树、改用 AG-Grid 的 valueFormatter 出纯文本。
14
+ *
15
+ * 本注册表负责「内层组件类型 -> 显示文本」的映射。命中返回格式化器,
16
+ * 未命中返回 null —— 调用方据此安全回退 AgField(正确优先于速度)。
17
+ *
18
+ * 取舍:这是 Formily readPretty 之外的一份精简显示逻辑,可能与定制 readPretty
19
+ * 发散。靠「未命中即回退 + 消费方可 registerReadOnlyFormatter 扩展」控制风险。
20
+ *
21
+ * @author nokecy
22
+ */
23
+
24
+ /** 从字段 schema / 列 props 里尽量取到 Select 的可选项(value->label 映射用) */
25
+ var resolveOptions = function resolveOptions(ctx) {
26
+ var _ref, _ref2, _ref3, _fieldSchema$enum, _fieldSchema$xCompon, _fieldSchema$xCompon2;
27
+ var columnProps = ctx.columnProps,
28
+ fieldSchema = ctx.fieldSchema;
29
+ var candidate = (_ref = (_ref2 = (_ref3 = (_fieldSchema$enum = fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.enum) !== null && _fieldSchema$enum !== void 0 ? _fieldSchema$enum : fieldSchema === null || fieldSchema === void 0 || (_fieldSchema$xCompon = fieldSchema['x-component-props']) === null || _fieldSchema$xCompon === void 0 ? void 0 : _fieldSchema$xCompon.options) !== null && _ref3 !== void 0 ? _ref3 : fieldSchema === null || fieldSchema === void 0 || (_fieldSchema$xCompon2 = fieldSchema['x-component-props']) === null || _fieldSchema$xCompon2 === void 0 ? void 0 : _fieldSchema$xCompon2.dataSource) !== null && _ref2 !== void 0 ? _ref2 : columnProps === null || columnProps === void 0 ? void 0 : columnProps.options) !== null && _ref !== void 0 ? _ref : columnProps === null || columnProps === void 0 ? void 0 : columnProps.dataSource;
30
+ return Array.isArray(candidate) ? candidate : [];
31
+ };
32
+
33
+ /** 单个值映射成 label:兼容 labelInValue 对象、{label,value} 选项、原始值 */
34
+ var mapOptionLabel = function mapOptionLabel(value, options) {
35
+ var _ref4, _value$label, _ref5, _hit$label;
36
+ if (value == null) return '';
37
+ // labelInValue: 值本身就是 { label, value }
38
+ if (_typeof(value) === 'object') return String((_ref4 = (_value$label = value.label) !== null && _value$label !== void 0 ? _value$label : value.value) !== null && _ref4 !== void 0 ? _ref4 : '');
39
+ // 严格相等优先;退一步按 String 宽松比对,容忍后端类型漂移(如返回 "0" 而 enum 存数字 0)
40
+ var hit = options.find(function (o) {
41
+ var ov = o && _typeof(o) === 'object' ? o.value : o;
42
+ return ov === value || String(ov) === String(value);
43
+ });
44
+ if (hit && _typeof(hit) === 'object') return String((_ref5 = (_hit$label = hit.label) !== null && _hit$label !== void 0 ? _hit$label : hit.value) !== null && _ref5 !== void 0 ? _ref5 : value);
45
+ return String(value);
46
+ };
47
+ var textFormatter = function textFormatter(value) {
48
+ return value == null ? '' : String(value);
49
+ };
50
+ var selectFormatter = function selectFormatter(value, ctx) {
51
+ if (value == null) return '';
52
+ var options = resolveOptions(ctx);
53
+ // 多选:数组 -> 逗号拼接
54
+ if (Array.isArray(value)) {
55
+ return value.map(function (v) {
56
+ return mapOptionLabel(v, options);
57
+ }).filter(Boolean).join(', ');
58
+ }
59
+ return mapOptionLabel(value, options);
60
+ };
61
+ var dateFormatter = function dateFormatter(value, ctx) {
62
+ var _ref6, _ctx$columnProps$form, _ctx$columnProps, _ctx$fieldSchema;
63
+ if (value == null || value === '') return '';
64
+ var fmt = (_ref6 = (_ctx$columnProps$form = (_ctx$columnProps = ctx.columnProps) === null || _ctx$columnProps === void 0 ? void 0 : _ctx$columnProps.format) !== null && _ctx$columnProps$form !== void 0 ? _ctx$columnProps$form : (_ctx$fieldSchema = ctx.fieldSchema) === null || _ctx$fieldSchema === void 0 || (_ctx$fieldSchema = _ctx$fieldSchema['x-component-props']) === null || _ctx$fieldSchema === void 0 ? void 0 : _ctx$fieldSchema.format) !== null && _ref6 !== void 0 ? _ref6 : 'YYYY-MM-DD';
65
+ // 值多为 dayjs 对象(有 .format)或已格式化的字符串;不强引 dayjs,保持轻量
66
+ if (value && typeof value.format === 'function') return value.format(fmt);
67
+ return String(value);
68
+ };
69
+ var booleanFormatter = function booleanFormatter(value, ctx) {
70
+ var _ctx$fieldSchema$xCo, _ctx$fieldSchema2, _props$checkedChildre, _props$unCheckedChild;
71
+ if (value == null || value === '') return '';
72
+ var props = (_ctx$fieldSchema$xCo = (_ctx$fieldSchema2 = ctx.fieldSchema) === null || _ctx$fieldSchema2 === void 0 ? void 0 : _ctx$fieldSchema2['x-component-props']) !== null && _ctx$fieldSchema$xCo !== void 0 ? _ctx$fieldSchema$xCo : {};
73
+ var truthy = (_props$checkedChildre = props.checkedChildren) !== null && _props$checkedChildre !== void 0 ? _props$checkedChildre : '是';
74
+ var falsy = (_props$unCheckedChild = props.unCheckedChildren) !== null && _props$unCheckedChild !== void 0 ? _props$unCheckedChild : '否';
75
+ return value ? String(truthy) : String(falsy);
76
+ };
77
+
78
+ /**
79
+ * 内置注册表。key 为 Formily x-component 名。
80
+ * 未列出的组件类型 -> getReadOnlyFormatter 返回 null -> 回退 AgField。
81
+ */
82
+ var registry = {
83
+ Input: textFormatter,
84
+ 'Input.TextArea': textFormatter,
85
+ Password: textFormatter,
86
+ Text: textFormatter,
87
+ Preview: textFormatter,
88
+ NumberPicker: textFormatter,
89
+ InputNumber: textFormatter,
90
+ Select: selectFormatter,
91
+ TreeSelect: selectFormatter,
92
+ Cascader: selectFormatter,
93
+ 'Radio.Group': selectFormatter,
94
+ 'Checkbox.Group': selectFormatter,
95
+ DatePicker: dateFormatter,
96
+ TimePicker: dateFormatter,
97
+ Switch: booleanFormatter,
98
+ Checkbox: booleanFormatter
99
+ };
100
+
101
+ /** 消费方扩展自定义只读列的显示逻辑 */
102
+ var registerReadOnlyFormatter = exports.registerReadOnlyFormatter = function registerReadOnlyFormatter(component, formatter) {
103
+ registry[component] = formatter;
104
+ };
105
+
106
+ /**
107
+ * 取某组件类型的只读格式化器。命中返回函数,未命中返回 null(调用方回退 AgField)。
108
+ */
109
+ var getReadOnlyFormatter = exports.getReadOnlyFormatter = function getReadOnlyFormatter(component) {
110
+ var _registry$component;
111
+ if (!component) return null;
112
+ return (_registry$component = registry[component]) !== null && _registry$component !== void 0 ? _registry$component : null;
113
+ };
@@ -6,6 +6,6 @@ import { ObservableColumnSource } from './interface';
6
6
  declare const isColumnComponent: (schema: Schema) => boolean;
7
7
  declare const useArrayTableSources: () => ObservableColumnSource[];
8
8
  declare const useArrayTableActions: () => ObservableColumnSource[];
9
- declare const useArrayTableColumns: (dataSource: any[], field: ArrayField, sources: ObservableColumnSource[]) => AgGridReactProps['columnDefs'];
9
+ declare const buildArrayTableColumns: (dataSource: any[], field: ArrayField, sources: ObservableColumnSource[]) => AgGridReactProps['columnDefs'];
10
10
  declare const useAddition: () => React.JSX.Element | null;
11
- export { isColumnComponent, useArrayTableSources, useArrayTableActions, useArrayTableColumns, useAddition };
11
+ export { isColumnComponent, useArrayTableSources, useArrayTableActions, buildArrayTableColumns, useAddition };
@@ -4,12 +4,13 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.useArrayTableSources = exports.useArrayTableColumns = exports.useArrayTableActions = exports.useAddition = exports.isColumnComponent = void 0;
7
+ exports.useArrayTableSources = exports.useArrayTableActions = exports.useAddition = exports.isColumnComponent = exports.buildArrayTableColumns = void 0;
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
  var _react2 = require("@formily/react");
10
10
  var _shared = require("@formily/shared");
11
11
  var _arrayBase = _interopRequireDefault(require("./arrayBase"));
12
- var _excluded = ["hide", "sort", "sortIndex"];
12
+ var _readOnlyFormatters = require("./readOnlyFormatters");
13
+ var _excluded = ["hide", "sort", "sortIndex", "forceAgField"];
13
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
15
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
15
16
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -109,24 +110,26 @@ var useArrayTableActions = exports.useArrayTableActions = function useArrayTable
109
110
  return schema.properties ? parseSources(schema.properties['actions'] || {}) : [];
110
111
  };
111
112
  var AgField = function AgField(_ref) {
112
- var _ref2, _node$rowIndex;
113
+ var _field$value$indexOf, _field$value, _field$value$indexOf2, _ref2, _node$rowIndex;
113
114
  var value = _ref.value,
114
115
  record = _ref.data,
115
116
  dataSource = _ref.dataSource,
116
117
  schema = _ref.schema,
117
118
  field = _ref.field,
118
119
  node = _ref.node;
119
- // 【修复】优先使用 AG-Grid 的 node.rowIndex,避免依赖 dataSource
120
- // 这样即使 columnDefs 中的 dataSource 是空数组,也能正确获取索引
121
- var index = (_ref2 = (_node$rowIndex = node === null || node === void 0 ? void 0 : node.rowIndex) !== null && _node$rowIndex !== void 0 ? _node$rowIndex : dataSource === null || dataSource === void 0 ? void 0 : dataSource.indexOf(record)) !== null && _ref2 !== void 0 ? _ref2 : -1;
120
+ // 数据序绑定:用 field.value.indexOf(record) 取数据数组下标(record === field.value 元素引用)。
121
+ // 排序/过滤后 node.rowIndex 是显示序 ≠ 数据序,会把单元格绑到别的行——故 indexOf 优先,
122
+ // 仅在未命中(理论不应发生)时才回退 rowIndex/dataSource。@author nokecy
123
+ var dataIndex = (_field$value$indexOf = field === null || field === void 0 || (_field$value = field.value) === null || _field$value === void 0 || (_field$value$indexOf2 = _field$value.indexOf) === null || _field$value$indexOf2 === void 0 ? void 0 : _field$value$indexOf2.call(_field$value, record)) !== null && _field$value$indexOf !== void 0 ? _field$value$indexOf : -1;
124
+ var index = dataIndex >= 0 ? dataIndex : (_ref2 = (_node$rowIndex = node === null || node === void 0 ? void 0 : node.rowIndex) !== null && _node$rowIndex !== void 0 ? _node$rowIndex : dataSource === null || dataSource === void 0 ? void 0 : dataSource.indexOf(record)) !== null && _ref2 !== void 0 ? _ref2 : -1;
122
125
  var children =
123
126
  /*#__PURE__*/
124
127
  //@ts-ignore
125
128
  _react.default.createElement(_arrayBase.default.Item, {
126
129
  index: index,
127
130
  record: function record() {
128
- var _field$value;
129
- return (_field$value = field.value) === null || _field$value === void 0 ? void 0 : _field$value[index];
131
+ var _field$value2;
132
+ return (_field$value2 = field.value) === null || _field$value2 === void 0 ? void 0 : _field$value2[index];
130
133
  },
131
134
  schema: schema,
132
135
  field: field
@@ -137,7 +140,108 @@ var AgField = function AgField(_ref) {
137
140
  }));
138
141
  return children;
139
142
  };
140
- var useArrayTableColumns = exports.useArrayTableColumns = function useArrayTableColumns(dataSource, field, sources) {
143
+
144
+ /**
145
+ * 懒挂载单元格渲染器(可编辑列)。
146
+ *
147
+ * 已有行的可编辑格被 Editable 装饰器默认转成 readPretty 只读文本态(点击才进编辑),
148
+ * 但仍挂着完整 Formily 树——这是行多列多滚动卡的主因。本渲染器:
149
+ * - 新增行(_isNew,保持编辑态需即时校验) 或 已被激活(点击/导航进过)的格 -> 挂 AgField 全树;
150
+ * - 其余(存量行、没碰过) -> 只渲染廉价纯文本(复用 readOnlyFormatters),不挂 Formily 树。
151
+ *
152
+ * 激活态存放在 AG-Grid context.activeCells(Set),由 index.tsx 在点击/键盘导航时写入并 refreshCells。
153
+ * 「挂了不卸」:一旦激活保持挂载(直到行被虚拟化销毁),不做失焦退回,避开一堆边界。
154
+ *
155
+ * 校验安全:未碰过的存量格本就是 readPretty、本就不参与校验,不挂树校验语义零变化。@author nokecy
156
+ */
157
+ var LazyAgField = function LazyAgField(params) {
158
+ var _context$activeCells, _context$activeCells$;
159
+ var value = params.value,
160
+ record = params.data,
161
+ dataSource = params.dataSource,
162
+ schema = params.schema,
163
+ field = params.field,
164
+ node = params.node,
165
+ colDef = params.colDef,
166
+ context = params.context,
167
+ formatter = params.formatter,
168
+ columnProps = params.columnProps,
169
+ fieldSchema = params.fieldSchema;
170
+ var key = "".concat(node === null || node === void 0 ? void 0 : node.id, ":").concat(colDef === null || colDef === void 0 ? void 0 : colDef.field);
171
+ var activated = (record === null || record === void 0 ? void 0 : record._isNew) === true || (context === null || context === void 0 || (_context$activeCells = context.activeCells) === null || _context$activeCells === void 0 || (_context$activeCells$ = _context$activeCells.has) === null || _context$activeCells$ === void 0 ? void 0 : _context$activeCells$.call(_context$activeCells, key)) === true;
172
+ if (activated) {
173
+ return /*#__PURE__*/_react.default.createElement(AgField, {
174
+ value: value,
175
+ data: record,
176
+ dataSource: dataSource,
177
+ schema: schema,
178
+ field: field,
179
+ node: node
180
+ });
181
+ }
182
+ var text = formatter ? formatter(value, {
183
+ columnProps: columnProps,
184
+ fieldSchema: fieldSchema
185
+ }) : value == null ? '' : String(value);
186
+ // 纯文本占满单元格,点击交给 AG-Grid onCellClicked 激活;样式尽量贴近 Editable 只读态避免点开跳动
187
+ return /*#__PURE__*/_react.default.createElement("span", {
188
+ className: "ag-array-table-lazy-text",
189
+ style: {
190
+ display: 'inline-block',
191
+ width: '100%',
192
+ cursor: 'text'
193
+ }
194
+ }, text);
195
+ };
196
+
197
+ // 在 Column 的子 schema 里递归找到内层数据字段(可读 x-component / x-pattern / x-reactions / enum) @author nokecy
198
+ var findDataFieldSchema = function findDataFieldSchema(columnSchema, name) {
199
+ if (!columnSchema || !columnSchema.properties) return null;
200
+ var matched = null;
201
+ var firstField = null;
202
+ var walk = function walk(s) {
203
+ if (!s || !s.properties) return;
204
+ s.reduceProperties(function (_, child) {
205
+ if (matched) return _;
206
+ var comp = child === null || child === void 0 ? void 0 : child['x-component'];
207
+ // 兜底:记录第一个带 x-component 的叶子字段(排除 Column/Operations/Addition 等包裹组件)
208
+ if (!firstField && typeof comp === 'string' && !/Column|Operations|Addition/.test(comp)) {
209
+ firstField = child;
210
+ }
211
+ if ((child === null || child === void 0 ? void 0 : child.name) === name) {
212
+ matched = child;
213
+ return _;
214
+ }
215
+ walk(child);
216
+ return _;
217
+ }, null);
218
+ };
219
+ walk(columnSchema);
220
+ return matched || firstField;
221
+ };
222
+
223
+ /**
224
+ * 判断某列是否可走「只读纯文本快路径」(不挂 Formily 树)。
225
+ *
226
+ * 安全不对称:误判「可编辑->只读」会丢编辑/校验/reaction 计算(灾难);
227
+ * 误判「只读->可编辑」只是没优化(无害)。所以仅在能证明永久只读时才放行,其余一律回退。
228
+ *
229
+ * @author nokecy
230
+ */
231
+ var isColumnReadOnlyEligible = function isColumnReadOnlyEligible(arrayPattern, dataField, columnProps) {
232
+ if ((columnProps === null || columnProps === void 0 ? void 0 : columnProps.forceAgField) === true) return false;
233
+ // 有 x-reactions:可能运行时切 pattern 或计算字段值,静态判不准 -> 保守回退 AgField
234
+ if (dataField && dataField['x-reactions']) return false;
235
+ if (arrayPattern === 'readPretty') return true; // 整表只读(明细/详情页)
236
+ if (!dataField) return false;
237
+ if (dataField['x-pattern'] === 'readPretty') return true;
238
+ if (dataField['x-read-pretty'] === true) return true;
239
+ return false;
240
+ };
241
+
242
+ // 重命名自 useArrayTableColumns:内部无任何 Hook 调用,use 前缀违反 Hook 命名约定且曾在 useMemo 内被调用 @author nokecy
243
+ var buildArrayTableColumns = exports.buildArrayTableColumns = function buildArrayTableColumns(dataSource, field, sources) {
244
+ var arrayPattern = field === null || field === void 0 ? void 0 : field.pattern;
141
245
  return sources.reduce(function (buf, _ref3, key) {
142
246
  var name = _ref3.name,
143
247
  columnProps = _ref3.columnProps,
@@ -154,13 +258,60 @@ var useArrayTableColumns = exports.useArrayTableColumns = function useArrayTable
154
258
  var hide = columnProps.hide,
155
259
  sort = columnProps.sort,
156
260
  sortIndex = columnProps.sortIndex,
261
+ forceAgField = columnProps.forceAgField,
157
262
  safeColumnProps = _objectWithoutProperties(columnProps, _excluded);
158
- return buf.concat(_objectSpread(_objectSpread({}, safeColumnProps), {}, {
263
+ var base = _objectSpread(_objectSpread({}, safeColumnProps), {}, {
159
264
  // 保留 width 作为列的初始宽度
160
265
  width: columnProps.width,
161
266
  //@ts-ignore
162
267
  headerName: columnProps.headerName || columnProps.title,
163
- field: name,
268
+ field: name
269
+ });
270
+
271
+ // 三分流渲染策略:@author nokecy
272
+ // ① 只读纯文本(永不可编辑):只读列 + 有格式化器 -> valueFormatter,不挂 Formily 树。
273
+ // ② 可编辑懒挂载:可编辑列 + 有格式化器 + 无 reactions + 未强制 eager -> LazyAgField,
274
+ // 存量格先出廉价文本、点击/导航才挂全树(挂了不卸)。
275
+ // ③ 兜底全树:其余(无格式化器/带 reactions/forceAgField/只读但无格式化器) -> AgField。
276
+ var dataField = findDataFieldSchema(schema, name);
277
+ var component = dataField === null || dataField === void 0 ? void 0 : dataField['x-component'];
278
+ var formatter = (0, _readOnlyFormatters.getReadOnlyFormatter)(component);
279
+ var readOnly = isColumnReadOnlyEligible(arrayPattern, dataField, columnProps);
280
+ var hasReactions = !!(dataField && dataField['x-reactions']);
281
+ var forceEager = (columnProps === null || columnProps === void 0 ? void 0 : columnProps.forceAgField) === true;
282
+
283
+ // ① 只读纯文本
284
+ if (readOnly && formatter) {
285
+ return buf.concat(_objectSpread(_objectSpread({}, base), {}, {
286
+ // 显式清掉可能从 safeColumnProps 漏带的 cellRenderer(AG-Grid 中 renderer 优先级高于 formatter)
287
+ cellRenderer: undefined,
288
+ valueFormatter: function valueFormatter(params) {
289
+ return formatter(params.value, {
290
+ columnProps: columnProps,
291
+ fieldSchema: dataField
292
+ });
293
+ }
294
+ }));
295
+ }
296
+
297
+ // ② 可编辑懒挂载
298
+ if (!readOnly && formatter && !hasReactions && !forceEager) {
299
+ return buf.concat(_objectSpread(_objectSpread({}, base), {}, {
300
+ cellRenderer: LazyAgField,
301
+ cellRendererParams: {
302
+ dataSource: dataSource,
303
+ schema: schema,
304
+ field: field,
305
+ formatter: formatter,
306
+ columnProps: columnProps,
307
+ fieldSchema: dataField,
308
+ lazyEditable: true // 供 index.tsx 识别懒列(激活/导航用)
309
+ }
310
+ }));
311
+ }
312
+
313
+ // ③ 兜底全树
314
+ return buf.concat(_objectSpread(_objectSpread({}, base), {}, {
164
315
  cellRendererParams: {
165
316
  dataSource: dataSource,
166
317
  schema: schema,
@@ -107,7 +107,9 @@ var InternalEditable = (0, _react.observer)(function (props) {
107
107
  var input = (_innerRef$current = innerRef.current) === null || _innerRef$current === void 0 ? void 0 : _innerRef$current.querySelector('input:not([readonly]):not([disabled]), textarea:not([readonly]):not([disabled])');
108
108
  if (input) {
109
109
  input.focus();
110
- if ('setSelectionRange' in input && input.type !== 'number' && input.type !== 'date') {
110
+ // setSelectionRange 仅 textarea 与 text/search/url/tel/password 类型 input 支持;
111
+ // checkbox/number/date 等会抛 InvalidStateError,故用白名单守卫。@author nokecy
112
+ if (input.tagName === 'TEXTAREA' || /^(text|search|url|tel|password)$/i.test(input.type || 'text')) {
111
113
  var _input$value;
112
114
  var length = ((_input$value = input.value) === null || _input$value === void 0 ? void 0 : _input$value.length) || 0;
113
115
  setTimeout(function () {