@pisell/materials 6.11.212 → 6.11.214

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 (63) hide show
  1. package/build/lowcode/assets-daily.json +11 -11
  2. package/build/lowcode/assets-dev.json +2 -2
  3. package/build/lowcode/assets-prod.json +11 -11
  4. package/build/lowcode/meta.js +1 -1
  5. package/build/lowcode/render/default/view.css +1 -1
  6. package/build/lowcode/render/default/view.js +6 -6
  7. package/build/lowcode/view.css +1 -1
  8. package/build/lowcode/view.js +5 -5
  9. package/es/components/PisellTabbar/PisellTabbar.js +35 -8
  10. package/es/components/PisellTabbar/template/Template1/PisellTabbar.js +35 -8
  11. package/es/components/PisellTabbar/types.d.ts +2 -0
  12. package/es/components/pisellFind/index.d.ts +9 -4
  13. package/es/components/pisellFind/index.js +46 -13
  14. package/es/components/pisellLookup/PisellLookup.js +7 -2
  15. package/es/components/pisellLookup/components/LookupTrigger.js +36 -9
  16. package/es/components/pisellLookup/types.d.ts +63 -0
  17. package/es/components/pisellRecordBoard/shellFrame/ToolBar/ToolBarFilter.less +9 -2
  18. package/es/components/pisellRecordBoard/shellFrame/ToolBar/index.js +33 -9
  19. package/es/components/pisellRecordBoard/shellFrame/ToolBar/recordBoardToolbar.less +86 -11
  20. package/es/components/pisellRecordBoard/shellFrame/index.js +1 -0
  21. package/es/components/pisellRecordBoard/types.d.ts +7 -0
  22. package/es/components/pisellShellFrame/PisellShellFrame.less +5 -0
  23. package/es/components/pisellTimeRangeDisplay/PisellTimeRangeDisplay.js +6 -1
  24. package/es/components/pisellTimeRangeDisplay/components/TimeRangeBlock.js +53 -20
  25. package/es/components/productCard/lineItem/BookingLineItem.js +95 -32
  26. package/es/components/productCard/lineItem/index.js +9 -1
  27. package/es/components/productCard/lineItem/index.less +33 -0
  28. package/es/components/productCard/lineItem/locales.js +20 -5
  29. package/es/index.d.ts +1 -1
  30. package/lib/components/PisellTabbar/PisellTabbar.js +16 -4
  31. package/lib/components/PisellTabbar/template/Template1/PisellTabbar.js +16 -4
  32. package/lib/components/PisellTabbar/types.d.ts +2 -0
  33. package/lib/components/pisellFind/index.d.ts +9 -4
  34. package/lib/components/pisellFind/index.js +29 -10
  35. package/lib/components/pisellLookup/PisellLookup.js +9 -1
  36. package/lib/components/pisellLookup/components/LookupTrigger.js +17 -0
  37. package/lib/components/pisellLookup/types.d.ts +63 -0
  38. package/lib/components/pisellRecordBoard/shellFrame/ToolBar/ToolBarFilter.less +9 -2
  39. package/lib/components/pisellRecordBoard/shellFrame/ToolBar/index.js +21 -6
  40. package/lib/components/pisellRecordBoard/shellFrame/ToolBar/recordBoardToolbar.less +86 -11
  41. package/lib/components/pisellRecordBoard/shellFrame/index.js +1 -0
  42. package/lib/components/pisellRecordBoard/types.d.ts +7 -0
  43. package/lib/components/pisellShellFrame/PisellShellFrame.less +5 -0
  44. package/lib/components/pisellTimeRangeDisplay/PisellTimeRangeDisplay.js +6 -1
  45. package/lib/components/pisellTimeRangeDisplay/components/TimeRangeBlock.js +37 -20
  46. package/lib/components/productCard/lineItem/BookingLineItem.js +93 -43
  47. package/lib/components/productCard/lineItem/index.js +9 -1
  48. package/lib/components/productCard/lineItem/index.less +33 -0
  49. package/lib/components/productCard/lineItem/locales.js +20 -5
  50. package/lib/index.d.ts +1 -1
  51. package/package.json +2 -2
  52. package/es/components/pisellTimeRangeDisplay/PisellTimeRangeDisplay.d.ts +0 -32
  53. package/es/components/pisellTimeRangeDisplay/components/TimeRangeBlock.d.ts +0 -30
  54. package/es/components/pisellTimeRangeDisplay/types.d.ts +0 -137
  55. package/es/components/productCard/lineItem/BookingLineItem.d.ts +0 -19
  56. package/es/components/productCard/lineItem/index.d.ts +0 -69
  57. package/es/components/productCard/lineItem/locales.d.ts +0 -23
  58. package/lib/components/pisellTimeRangeDisplay/PisellTimeRangeDisplay.d.ts +0 -32
  59. package/lib/components/pisellTimeRangeDisplay/components/TimeRangeBlock.d.ts +0 -30
  60. package/lib/components/pisellTimeRangeDisplay/types.d.ts +0 -137
  61. package/lib/components/productCard/lineItem/BookingLineItem.d.ts +0 -19
  62. package/lib/components/productCard/lineItem/index.d.ts +0 -69
  63. package/lib/components/productCard/lineItem/locales.d.ts +0 -23
@@ -5,8 +5,14 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
5
5
  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; }
6
6
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
7
  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); }
8
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
9
+ 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."); }
10
+ 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); }
11
+ 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; }
12
+ 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; } }
13
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
14
  import classNames from 'classnames';
9
- import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef } from 'react';
15
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
10
16
  import { getText } from "../../locales";
11
17
  import PisellCards from "../PisellCards";
12
18
  import SuperTabs from "../PisellSuperTabs";
@@ -80,7 +86,8 @@ var PisellTabbar = /*#__PURE__*/forwardRef(function (props, ref) {
80
86
  customExpandConfig = props.expandConfig,
81
87
  _props$maxLevel = props.maxLevel,
82
88
  maxLevel = _props$maxLevel === void 0 ? 3 : _props$maxLevel,
83
- _onSearch = props.onSearch;
89
+ _onSearch = props.onSearch,
90
+ searchProps = props.searchProps;
84
91
  var containerRef = useRef(null);
85
92
  var tabbarIdRef = useRef(createTabbarId());
86
93
  var searchRef = useRef(null);
@@ -116,6 +123,14 @@ var PisellTabbar = /*#__PURE__*/forwardRef(function (props, ref) {
116
123
  // 展开配置
117
124
  var expandConfigData = customExpandConfig || getExpandConfig();
118
125
 
126
+ /**
127
+ * 搜索弹层是否展开:展开时隐藏分类切换,仅保留搜索入口。
128
+ */
129
+ var _useState = useState(false),
130
+ _useState2 = _slicedToArray(_useState, 2),
131
+ isSearchOpen = _useState2[0],
132
+ setIsSearchOpen = _useState2[1];
133
+
119
134
  /**
120
135
  * 打开搜索模式
121
136
  *
@@ -126,6 +141,7 @@ var PisellTabbar = /*#__PURE__*/forwardRef(function (props, ref) {
126
141
  setCacheActiveKey(activeKey);
127
142
  _setActiveKey([]);
128
143
  onChange === null || onChange === void 0 || onChange([]);
144
+ setIsSearchOpen(true);
129
145
  });
130
146
 
131
147
  /**
@@ -137,6 +153,7 @@ var PisellTabbar = /*#__PURE__*/forwardRef(function (props, ref) {
137
153
  var closeSearchMode = useMemoizedFn(function () {
138
154
  _onSearch === null || _onSearch === void 0 || _onSearch('');
139
155
  resetActiveKey();
156
+ setIsSearchOpen(false);
140
157
  });
141
158
 
142
159
  //@ts-ignore
@@ -260,8 +277,15 @@ var PisellTabbar = /*#__PURE__*/forwardRef(function (props, ref) {
260
277
  * 一级数据源
261
278
  */
262
279
  var level1DataSource = useMemo(function () {
263
- return addDataSourceItemsByKey(dataSource, LEVEL_ADD_ITEMS.level1);
264
- }, [dataSource]);
280
+ var full = addDataSourceItemsByKey(dataSource, LEVEL_ADD_ITEMS.level1);
281
+ // 搜索弹层展开时,隐藏分类切换(普通分类 / 全部 / 展开),仅保留搜索入口本身。
282
+ if (isSearchOpen) {
283
+ return full.filter(function (item) {
284
+ return (item === null || item === void 0 ? void 0 : item.key) === 'search';
285
+ });
286
+ }
287
+ return full;
288
+ }, [dataSource, isSearchOpen]);
265
289
  var level2Expand = getExpand('level2');
266
290
  var level3Expand = getExpand('level3');
267
291
  var level3ScrollViewProps = useMemo(function () {
@@ -436,9 +460,12 @@ var PisellTabbar = /*#__PURE__*/forwardRef(function (props, ref) {
436
460
  }));
437
461
  }, [expand]);
438
462
  var renderSearch = useCallback(function (itemProps, level) {
439
- return /*#__PURE__*/React.createElement(PisellFind, {
463
+ return /*#__PURE__*/React.createElement(PisellFind, _extends({
440
464
  showHistory: false,
441
- modalWidth: '100%',
465
+ modalWidth: '100%'
466
+ }, searchProps, {
467
+ /** 仅在搜索弹层打开时才开启扫码监听:tabbar 的 Find 常驻挂载,关闭时不应长期占用扫码焦点 */
468
+ enableScanner: Boolean(searchProps === null || searchProps === void 0 ? void 0 : searchProps.enableScanner) && isSearchOpen,
442
469
  ref: searchRef,
443
470
  onSearch: function onSearch(e) {
444
471
  _onSearch === null || _onSearch === void 0 || _onSearch(e);
@@ -477,8 +504,8 @@ var PisellTabbar = /*#__PURE__*/forwardRef(function (props, ref) {
477
504
  return renderLevelNCard(_cardProps, level);
478
505
  }
479
506
  }))
480
- });
481
- }, [activeKey]);
507
+ }));
508
+ }, [activeKey, isSearchOpen]);
482
509
  /**
483
510
  * 渲染一级 Tab 项
484
511
  */
@@ -5,8 +5,14 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
5
5
  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; }
6
6
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
7
  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); }
8
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
9
+ 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."); }
10
+ 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); }
11
+ 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; }
12
+ 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; } }
13
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
14
  import classNames from 'classnames';
9
- import React, { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef } from 'react';
15
+ import React, { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from 'react';
10
16
  import { getText } from "../../../../locales";
11
17
  import PisellCards from "../../../PisellCards";
12
18
  import SuperTabs from "../../../PisellSuperTabs";
@@ -44,7 +50,8 @@ var PisellTabbar = function PisellTabbar(props, ref) {
44
50
  customExpandConfig = props.expandConfig,
45
51
  _props$maxLevel = props.maxLevel,
46
52
  maxLevel = _props$maxLevel === void 0 ? 3 : _props$maxLevel,
47
- _onSearch = props.onSearch;
53
+ _onSearch = props.onSearch,
54
+ searchProps = props.searchProps;
48
55
  var containerRef = useRef(null);
49
56
  var searchRef = useRef(null);
50
57
 
@@ -93,6 +100,14 @@ var PisellTabbar = function PisellTabbar(props, ref) {
93
100
  return getActiveKey(2);
94
101
  }, [activeKey]);
95
102
 
103
+ /**
104
+ * 搜索弹层是否展开:展开时隐藏分类切换,仅保留搜索入口。
105
+ */
106
+ var _useState = useState(false),
107
+ _useState2 = _slicedToArray(_useState, 2),
108
+ isSearchOpen = _useState2[0],
109
+ setIsSearchOpen = _useState2[1];
110
+
96
111
  /**
97
112
  * 打开搜索模式
98
113
  */
@@ -100,6 +115,7 @@ var PisellTabbar = function PisellTabbar(props, ref) {
100
115
  setCacheActiveKey(activeKey);
101
116
  _setActiveKey([]);
102
117
  onChange === null || onChange === void 0 || onChange([]);
118
+ setIsSearchOpen(true);
103
119
  };
104
120
 
105
121
  /**
@@ -108,6 +124,7 @@ var PisellTabbar = function PisellTabbar(props, ref) {
108
124
  var closeSearchMode = function closeSearchMode() {
109
125
  _onSearch === null || _onSearch === void 0 || _onSearch('');
110
126
  resetActiveKey();
127
+ setIsSearchOpen(false);
111
128
  };
112
129
 
113
130
  //@ts-ignore
@@ -202,9 +219,12 @@ var PisellTabbar = function PisellTabbar(props, ref) {
202
219
  }));
203
220
  }, [expandConfig, activeKey, getLevelConfig]);
204
221
  var renderSearch = useCallback(function (itemProps, level) {
205
- return /*#__PURE__*/React.createElement(PisellFind, {
222
+ return /*#__PURE__*/React.createElement(PisellFind, _extends({
206
223
  showHistory: false,
207
- modalWidth: '100%',
224
+ modalWidth: '100%'
225
+ }, searchProps, {
226
+ /** 仅在搜索弹层打开时才开启扫码监听:tabbar 的 Find 常驻挂载,关闭时不应长期占用扫码焦点 */
227
+ enableScanner: Boolean(searchProps === null || searchProps === void 0 ? void 0 : searchProps.enableScanner) && isSearchOpen,
208
228
  ref: searchRef,
209
229
  onSearch: function onSearch(e) {
210
230
  _onSearch === null || _onSearch === void 0 || _onSearch(e);
@@ -243,8 +263,8 @@ var PisellTabbar = function PisellTabbar(props, ref) {
243
263
  return renderNormalCard(_cardProps, level);
244
264
  }
245
265
  }))
246
- });
247
- }, [activeKey, tabbarId]);
266
+ }));
267
+ }, [activeKey, tabbarId, isSearchOpen]);
248
268
 
249
269
  /**
250
270
  * 渲染 level2/level3 普通卡片
@@ -284,8 +304,15 @@ var PisellTabbar = function PisellTabbar(props, ref) {
284
304
  * 一级 Tabbar 数据源
285
305
  */
286
306
  var level1DataSource = useMemo(function () {
287
- return addDataSourceItemsByKey(dataSource, LEVEL_ADD_ITEMS.level1);
288
- }, [dataSource]);
307
+ var full = addDataSourceItemsByKey(dataSource, LEVEL_ADD_ITEMS.level1);
308
+ // 搜索弹层展开时,隐藏分类切换(普通分类 / 全部 / 展开),仅保留搜索入口本身。
309
+ if (isSearchOpen) {
310
+ return full.filter(function (item) {
311
+ return (item === null || item === void 0 ? void 0 : item.key) === 'search';
312
+ });
313
+ }
314
+ return full;
315
+ }, [dataSource, isSearchOpen]);
289
316
 
290
317
  /**
291
318
  * 渲染一级 Tab Item
@@ -83,6 +83,8 @@ export interface PisellTabbarProps {
83
83
  /** 最大层级数 */
84
84
  maxLevel?: 1 | 2 | 3;
85
85
  onSearch?: (value: string) => void;
86
+ /** 透传给内部 PisellFind 的搜索配置(如 inputRender 插槽)。 */
87
+ searchProps?: Record<string, any>;
86
88
  __designMode?: boolean;
87
89
  }
88
90
  export interface PisellTabbarRef {
@@ -20,8 +20,11 @@ export interface PisellFindScannerData {
20
20
  export interface PisellFindProps extends PisellLookupProps {
21
21
  /**
22
22
  * 是否开启扫码枪监听
23
- * 通过宿主 `app.pubsub.subscribe('nativeScanResult', ...)` 订阅;
24
- * 切换 false 时会 unsubscribe,停止接收事件。
23
+ * - 优先:通过宿主 `appHelper.utils.acquireScanFocus` 接入「扫码焦点栈」,
24
+ * 保证同一页面存在多个 PisellFind 时,只有「栈顶」(最后开启监听的那个,
25
+ * 如列表上方拉起的弹窗)响应扫码,底层组件不响应;关闭/卸载时自动释放,焦点回退。
26
+ * - 回退:宿主未注册焦点栈时,退回到直连 `app.pubsub.subscribe('nativeScanResult', ...)`。
27
+ * 切换 false 时会释放焦点 / unsubscribe,停止接收事件。
25
28
  * @default false
26
29
  */
27
30
  enableScanner?: boolean;
@@ -46,8 +49,10 @@ export declare type PisellFindRef = PisellLookupRef;
46
49
  * - 默认不显示确认按钮(输入即搜索)
47
50
  * - 默认开启搜索历史
48
51
  * - 默认不展示结果区(结果在页面其他位置展示)
49
- * - 通过 `enableScanner` 接入扫码枪:使用宿主 `app.pubsub.subscribe(SCAN_RESULT_EVENT, ...)`,
50
- * 每次扫码直接覆盖输入框内容并触发 onSearch / onScannerData;切回 false 时自动 unsubscribe。
52
+ * - 通过 `enableScanner` 接入扫码枪:优先走宿主注入的「扫码焦点栈」
53
+ * (`appHelper.utils.acquireScanFocus`),保证同页多个 PisellFind 只有栈顶响应;
54
+ * 宿主未注册时回退到直连 `app.pubsub.subscribe(SCAN_RESULT_EVENT, ...)`。
55
+ * 每次扫码直接覆盖输入框内容并触发 onSearch / onScannerData;切回 false 时自动释放 / unsubscribe。
51
56
  *
52
57
  * @example
53
58
  * ```tsx
@@ -38,8 +38,10 @@ export var SCAN_RESULT_EVENT = 'nativeScanResult';
38
38
  * - 默认不显示确认按钮(输入即搜索)
39
39
  * - 默认开启搜索历史
40
40
  * - 默认不展示结果区(结果在页面其他位置展示)
41
- * - 通过 `enableScanner` 接入扫码枪:使用宿主 `app.pubsub.subscribe(SCAN_RESULT_EVENT, ...)`,
42
- * 每次扫码直接覆盖输入框内容并触发 onSearch / onScannerData;切回 false 时自动 unsubscribe。
41
+ * - 通过 `enableScanner` 接入扫码枪:优先走宿主注入的「扫码焦点栈」
42
+ * (`appHelper.utils.acquireScanFocus`),保证同页多个 PisellFind 只有栈顶响应;
43
+ * 宿主未注册时回退到直连 `app.pubsub.subscribe(SCAN_RESULT_EVENT, ...)`。
44
+ * 每次扫码直接覆盖输入框内容并触发 onSearch / onScannerData;切回 false 时自动释放 / unsubscribe。
43
45
  *
44
46
  * @example
45
47
  * ```tsx
@@ -52,7 +54,7 @@ export var SCAN_RESULT_EVENT = 'nativeScanResult';
52
54
  * ```
53
55
  */
54
56
  export var PisellFind = /*#__PURE__*/forwardRef(function (props, ref) {
55
- var _engineContext$appHel;
57
+ var _engineContext$appHel, _engineContext$appHel2, _appHelperUtils$busin;
56
58
  var _props$triggerType = props.triggerType,
57
59
  triggerType = _props$triggerType === void 0 ? 'button' : _props$triggerType,
58
60
  _props$buttonText = props.buttonText,
@@ -110,7 +112,7 @@ export var PisellFind = /*#__PURE__*/forwardRef(function (props, ref) {
110
112
  };
111
113
  }, []);
112
114
 
113
- /** 通过 useEngineContext 拿到宿主 app(含 pubsub.subscribe / unsubscribe */
115
+ /** 通过 useEngineContext 拿到宿主 app(含 pubsub.subscribe / unsubscribe)与扫码焦点栈 */
114
116
  var engineContext = useEngineContext();
115
117
  /**
116
118
  * 用 ref 稳定 getApp 引用:低代码环境下 engineContext 每次渲染可能返回新引用,
@@ -119,24 +121,28 @@ export var PisellFind = /*#__PURE__*/forwardRef(function (props, ref) {
119
121
  */
120
122
  var getAppRef = useRef(undefined);
121
123
  getAppRef.current = typeof (engineContext === null || engineContext === void 0 || (_engineContext$appHel = engineContext.appHelper) === null || _engineContext$appHel === void 0 || (_engineContext$appHel = _engineContext$appHel.utils) === null || _engineContext$appHel === void 0 ? void 0 : _engineContext$appHel.getApp) === 'function' ? engineContext.appHelper.utils.getApp : undefined;
124
+
125
+ /**
126
+ * 宿主可选注入的「扫码焦点栈」入口(acquireScanFocus)。
127
+ * 申请焦点后只有栈顶组件的回调会被触发;返回的 token.release() 用于释放焦点。
128
+ * 兼容两种注入位置:`appHelper.utils.acquireScanFocus` 或 `appHelper.utils.businessUtils.acquireScanFocus`
129
+ * (后者为宿主通过 bootstrap actions.appHelper.businessUtils 注入的常见方式)。
130
+ * 同样用 ref 稳定引用,effect 依赖只保留 enableScanner。
131
+ */
132
+ var acquireScanFocusRef = useRef(undefined);
133
+ var appHelperUtils = engineContext === null || engineContext === void 0 || (_engineContext$appHel2 = engineContext.appHelper) === null || _engineContext$appHel2 === void 0 ? void 0 : _engineContext$appHel2.utils;
134
+ acquireScanFocusRef.current = typeof (appHelperUtils === null || appHelperUtils === void 0 ? void 0 : appHelperUtils.acquireScanFocus) === 'function' ? appHelperUtils.acquireScanFocus : typeof (appHelperUtils === null || appHelperUtils === void 0 || (_appHelperUtils$busin = appHelperUtils.businessUtils) === null || _appHelperUtils$busin === void 0 ? void 0 : _appHelperUtils$busin.acquireScanFocus) === 'function' ? appHelperUtils.businessUtils.acquireScanFocus : undefined;
122
135
  useEffect(function () {
123
136
  if (!enableScanner) return undefined;
124
- var getApp = getAppRef.current;
125
- if (typeof getApp !== 'function') return undefined;
126
- var app = getApp();
127
- var pubsub = app === null || app === void 0 ? void 0 : app.pubsub;
128
- if (!pubsub || typeof pubsub.subscribe !== 'function') {
129
- return undefined;
130
- }
131
137
 
132
138
  /**
133
139
  * 监听回调:每次扫码直接覆盖输入框。
134
- * ScanResultPayload: { code, data },取 code 作为输入框值与搜索关键词。
140
+ * ScanResultPayload: { code, data },取 data 作为输入框值与搜索关键词。
135
141
  * setKeyword 在受控模式下会触发外部 onChange;onSearch 需要显式触发以驱动后续搜索流程
136
142
  * (受控模式下宿主一般只通过 onSearch 拿到新关键词,不会在 onChange 里再触发一次 onSearch,
137
143
  * 因此这里不会产生重复请求。如需自定义合流,可绑定 onScannerData 自行处理)。
138
144
  *
139
- * 非法 payload(无 codecode 为空串)直接忽略,避免把输入框/搜索条件意外清空。
145
+ * 非法 payload(无 datadata 为空串)直接忽略,避免把输入框/搜索条件意外清空。
140
146
  */
141
147
  var onScan = function onScan(payload) {
142
148
  var _lookupRef$current5, _onSearchRef$current, _onScannerDataRef$cur;
@@ -148,6 +154,33 @@ export var PisellFind = /*#__PURE__*/forwardRef(function (props, ref) {
148
154
  (_onSearchRef$current = onSearchRef.current) === null || _onSearchRef$current === void 0 || _onSearchRef$current.call(onSearchRef, data);
149
155
  (_onScannerDataRef$cur = onScannerDataRef.current) === null || _onScannerDataRef$cur === void 0 || _onScannerDataRef$cur.call(onScannerDataRef, payload);
150
156
  };
157
+
158
+ // 优先:接入宿主注入的「扫码焦点栈」,保证同页多个实例只有栈顶响应。
159
+ var acquireScanFocus = acquireScanFocusRef.current;
160
+ if (typeof acquireScanFocus === 'function') {
161
+ try {
162
+ var token = acquireScanFocus(onScan);
163
+ return function () {
164
+ try {
165
+ var _token$release;
166
+ token === null || token === void 0 || (_token$release = token.release) === null || _token$release === void 0 || _token$release.call(token);
167
+ } catch (e) {
168
+ console.warn('[PisellFind] release scan focus failed:', e);
169
+ }
170
+ };
171
+ } catch (e) {
172
+ console.warn('[PisellFind] acquire scan focus failed, fallback to pubsub:', e);
173
+ }
174
+ }
175
+
176
+ // 回退:宿主未注册焦点栈时,直连 pubsub(与改造前行为一致)。
177
+ var getApp = getAppRef.current;
178
+ if (typeof getApp !== 'function') return undefined;
179
+ var app = getApp();
180
+ var pubsub = app === null || app === void 0 ? void 0 : app.pubsub;
181
+ if (!pubsub || typeof pubsub.subscribe !== 'function') {
182
+ return undefined;
183
+ }
151
184
  try {
152
185
  pubsub.subscribe(SCAN_RESULT_EVENT, onScan);
153
186
  } catch (e) {
@@ -108,6 +108,7 @@ var PisellLookupComponent = /*#__PURE__*/forwardRef(function (props, ref) {
108
108
  clearOnClose = _props$clearOnClose === void 0 ? false : _props$clearOnClose,
109
109
  _props$autoFocusOnOpe = props.autoFocusOnOpen,
110
110
  autoFocusOnOpen = _props$autoFocusOnOpe === void 0 ? true : _props$autoFocusOnOpe,
111
+ inputRender = props.inputRender,
111
112
  className = props.className,
112
113
  style = props.style,
113
114
  zIndex = props.zIndex;
@@ -496,6 +497,8 @@ var PisellLookupComponent = /*#__PURE__*/forwardRef(function (props, ref) {
496
497
  confirmButtonText: confirmButtonText,
497
498
  showScan: showScan,
498
499
  value: keyword,
500
+ loading: loading,
501
+ inputRender: inputRender,
499
502
  onChange: handleInputChange,
500
503
  onClick: handleTriggerClick,
501
504
  onFocus: handleInputFocus,
@@ -565,9 +568,9 @@ var PisellLookupComponent = /*#__PURE__*/forwardRef(function (props, ref) {
565
568
  var hasAuxiliaryContent = showHistory && history.length > 0 || showSuggestions && suggestions.length > 0 && !!keyword || showHotWords && hotWords.length > 0 && !keyword;
566
569
 
567
570
  /**
568
- * 是否有结果区内容(loading 或有关键词且提供了 resultRender)
571
+ * 是否有结果区内容(须同时提供 resultRender;仅有 loading 时不展开空容器)
569
572
  */
570
- var hasResultsContent = Boolean(loading || keyword && resultRender);
573
+ var hasResultsContent = Boolean(resultRender && (loading || keyword));
571
574
 
572
575
  /**
573
576
  * 渲染内容区(辅助区 + 结果区)
@@ -639,6 +642,8 @@ var PisellLookupComponent = /*#__PURE__*/forwardRef(function (props, ref) {
639
642
  confirmButtonText: confirmButtonText,
640
643
  showScan: showScan,
641
644
  value: keyword,
645
+ loading: loading,
646
+ inputRender: inputRender,
642
647
  onChange: handleInputChange,
643
648
  onConfirm: handleConfirm,
644
649
  onScan: handleScan,
@@ -49,11 +49,13 @@ var LookupTriggerComponent = /*#__PURE__*/forwardRef(function (props, ref) {
49
49
  _props$showScan = props.showScan,
50
50
  showScan = _props$showScan === void 0 ? true : _props$showScan,
51
51
  value = props.value,
52
- onChange = props.onChange,
52
+ loading = props.loading,
53
+ inputRender = props.inputRender,
54
+ _onChange = props.onChange,
53
55
  onClick = props.onClick,
54
56
  onFocus = props.onFocus,
55
- onConfirm = props.onConfirm,
56
- onScan = props.onScan,
57
+ _onConfirm = props.onConfirm,
58
+ _onScan = props.onScan,
57
59
  onClear = props.onClear,
58
60
  onBlur = props.onBlur,
59
61
  _props$autoFocus = props.autoFocus,
@@ -96,14 +98,14 @@ var LookupTriggerComponent = /*#__PURE__*/forwardRef(function (props, ref) {
96
98
  * 处理输入变化
97
99
  */
98
100
  var handleChange = function handleChange(e) {
99
- onChange === null || onChange === void 0 || onChange(e.target.value);
101
+ _onChange === null || _onChange === void 0 || _onChange(e.target.value);
100
102
  };
101
103
 
102
104
  /**
103
105
  * 处理清除
104
106
  */
105
107
  var handleClear = function handleClear() {
106
- onChange === null || onChange === void 0 || onChange('');
108
+ _onChange === null || _onChange === void 0 || _onChange('');
107
109
  onClear === null || onClear === void 0 || onClear();
108
110
  };
109
111
 
@@ -140,7 +142,7 @@ var LookupTriggerComponent = /*#__PURE__*/forwardRef(function (props, ref) {
140
142
  hint: 17
141
143
  }
142
144
  }).then(function (res) {
143
- onScan === null || onScan === void 0 || onScan(res);
145
+ _onScan === null || _onScan === void 0 || _onScan(res);
144
146
  });
145
147
  // scanBarcode({ hint: 17 })
146
148
  // .then((res: { ScanResult: string }) => onScan?.(res?.ScanResult))
@@ -181,7 +183,7 @@ var LookupTriggerComponent = /*#__PURE__*/forwardRef(function (props, ref) {
181
183
  // 关闭扫码弹窗
182
184
  setScanVisible(false);
183
185
  // 触发扫码回调
184
- onScan === null || onScan === void 0 || onScan(code);
186
+ _onScan === null || _onScan === void 0 || _onScan(code);
185
187
  };
186
188
 
187
189
  /**
@@ -195,7 +197,7 @@ var LookupTriggerComponent = /*#__PURE__*/forwardRef(function (props, ref) {
195
197
  * 处理确认
196
198
  */
197
199
  var handleConfirm = function handleConfirm() {
198
- onConfirm === null || onConfirm === void 0 || onConfirm();
200
+ _onConfirm === null || _onConfirm === void 0 || _onConfirm();
199
201
  };
200
202
 
201
203
  /**
@@ -205,7 +207,7 @@ var LookupTriggerComponent = /*#__PURE__*/forwardRef(function (props, ref) {
205
207
  if (e.key === 'Enter') {
206
208
  var _ref2, _e$currentTarget$valu, _e$currentTarget;
207
209
  var currentValue = (_ref2 = (_e$currentTarget$valu = (_e$currentTarget = e.currentTarget) === null || _e$currentTarget === void 0 ? void 0 : _e$currentTarget.value) !== null && _e$currentTarget$valu !== void 0 ? _e$currentTarget$valu : value) !== null && _ref2 !== void 0 ? _ref2 : '';
208
- onConfirm === null || onConfirm === void 0 || onConfirm(currentValue);
210
+ _onConfirm === null || _onConfirm === void 0 || _onConfirm(currentValue);
209
211
  }
210
212
  };
211
213
 
@@ -213,6 +215,31 @@ var LookupTriggerComponent = /*#__PURE__*/forwardRef(function (props, ref) {
213
215
  * 渲染输入框触发器
214
216
  */
215
217
  var renderInputTrigger = function renderInputTrigger() {
218
+ // 输入栏插槽:把内部接好的受控状态 / 回调透传给自定义输入控件,替换内置 antd Input。
219
+ // button/icon/text 触发器不会走到这里,因此插槽只影响 input 形态。
220
+ if (inputRender) {
221
+ return inputRender({
222
+ value: value !== null && value !== void 0 ? value : '',
223
+ placeholder: placeholder,
224
+ disabled: disabled,
225
+ size: size,
226
+ loading: loading,
227
+ onChange: function onChange(v) {
228
+ return _onChange === null || _onChange === void 0 ? void 0 : _onChange(v);
229
+ },
230
+ onConfirm: function onConfirm(v) {
231
+ var _ref3;
232
+ return _onConfirm === null || _onConfirm === void 0 ? void 0 : _onConfirm((_ref3 = v !== null && v !== void 0 ? v : value) !== null && _ref3 !== void 0 ? _ref3 : '');
233
+ },
234
+ onClear: handleClear,
235
+ onScan: function onScan(code) {
236
+ return _onScan === null || _onScan === void 0 ? void 0 : _onScan(code);
237
+ },
238
+ onFocus: onFocus,
239
+ onBlur: onBlur
240
+ });
241
+ }
242
+
216
243
  // 构建前缀图标
217
244
  var prefix = showPrefixIcon ? prefixIcon || /*#__PURE__*/React.createElement(SearchOutlined, null) : undefined;
218
245
 
@@ -40,6 +40,40 @@ export interface PisellLookupRef {
40
40
  * Drawer 位置
41
41
  */
42
42
  export declare type DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';
43
+ /**
44
+ * 输入栏插槽上下文
45
+ *
46
+ * 通过 `inputRender` 自定义「输入框」形态触发器时,组件会把内部已经接好的受控状态与回调
47
+ * 透传给插槽。插槽只需把这些值绑定到自定义输入控件上,即可完全复用 PisellLookup 的
48
+ * 搜索状态机(受控值 / 防抖实时搜索 / 确认搜索 / 历史 / inline·popup 聚焦展开等)。
49
+ *
50
+ * 仅在 `triggerType='input'`(或 modal/drawer 内置输入框)形态下生效;button/icon/text
51
+ * 触发器不会调用 `inputRender`。
52
+ */
53
+ export interface LookupInputRenderContext {
54
+ /** 当前关键词(受控值) */
55
+ value: string;
56
+ /** 占位符 */
57
+ placeholder?: string;
58
+ /** 是否禁用 */
59
+ disabled?: boolean;
60
+ /** 尺寸 */
61
+ size?: SizeType;
62
+ /** 是否处于加载态(透传自 PisellLookup 的 loading) */
63
+ loading?: boolean;
64
+ /** 输入变化:写回关键词(受控) */
65
+ onChange: (value: string) => void;
66
+ /** 确认搜索:回车 / 点击搜索按钮时调用,可显式传入当前值 */
67
+ onConfirm: (value?: string) => void;
68
+ /** 清除:清空关键词并恢复结果 */
69
+ onClear: () => void;
70
+ /** 扫码结果回填 */
71
+ onScan?: (code: string) => void;
72
+ /** 聚焦:inline/popup 形态用于展开结果容器 */
73
+ onFocus?: () => void;
74
+ /** 失焦:inline/popup 形态用于延迟关闭结果容器 */
75
+ onBlur?: () => void;
76
+ }
43
77
  /**
44
78
  * PisellLookup 组件 Props
45
79
  */
@@ -328,6 +362,27 @@ export interface PisellLookupProps {
328
362
  * @default true
329
363
  */
330
364
  autoFocusOnOpen?: boolean;
365
+ /**
366
+ * 输入栏插槽
367
+ *
368
+ * 自定义「输入框」形态的触发器渲染。传入后会**替换内置 antd Input**,但完整复用
369
+ * PisellLookup 的搜索状态机(受控值 / 实时·确认搜索 / 历史 / 容器形态)。
370
+ * 仅 input 形态生效(含 modal/drawer 内置输入框),button/icon/text 触发器不受影响。
371
+ *
372
+ * @example
373
+ * ```tsx
374
+ * <PisellLookup
375
+ * inputRender={(ctx) => (
376
+ * <MyInput
377
+ * value={ctx.value}
378
+ * onChange={ctx.onChange}
379
+ * onSearch={ctx.onConfirm}
380
+ * />
381
+ * )}
382
+ * />
383
+ * ```
384
+ */
385
+ inputRender?: (ctx: LookupInputRenderContext) => React.ReactNode;
331
386
  /**
332
387
  * 自定义类名
333
388
  */
@@ -455,6 +510,14 @@ export interface LookupTriggerProps {
455
510
  * 是否自动聚焦
456
511
  */
457
512
  autoFocus?: boolean;
513
+ /**
514
+ * 加载态(透传给输入栏插槽 ctx.loading)
515
+ */
516
+ loading?: boolean;
517
+ /**
518
+ * 输入栏插槽:自定义 input 形态触发器渲染(仅 type='input' 生效)
519
+ */
520
+ inputRender?: (ctx: LookupInputRenderContext) => React.ReactNode;
458
521
  /**
459
522
  * 自定义类名
460
523
  */
@@ -30,7 +30,6 @@
30
30
  flex: 1;
31
31
  font-size: 16px !important;
32
32
  font-weight: 500 !important;
33
- padding: 0 16px !important;
34
33
  box-sizing: border-box !important;
35
34
  }
36
35
 
@@ -42,6 +41,9 @@
42
41
  align-items: center !important;
43
42
  justify-content: center !important;
44
43
  line-height: normal !important;
44
+ /** 仅约束左右 6px,不覆盖 antd / lowcode 默认的上下 padding */
45
+ padding-left: 6px !important;
46
+ padding-right: 6px !important;
45
47
  }
46
48
 
47
49
  /** 低代码:选中背景与 antd Button primary / 编辑平面图同源 */
@@ -65,7 +67,7 @@
65
67
  flex-wrap: nowrap;
66
68
  align-items: center;
67
69
  width: 100%;
68
- gap: 16px;
70
+ gap: 4px;
69
71
 
70
72
  .record-board-toolbar-find-wrap {
71
73
  flex: 1;
@@ -73,6 +75,11 @@
73
75
  display: flex;
74
76
  align-items: center;
75
77
 
78
+ /** RecordBoard 顶栏 SearchSection:仅此处 wrapper padding 5px,不改动组件默认 4px */
79
+ .comprehensive-search__search-input-wrapper {
80
+ padding: 5px;
81
+ }
82
+
76
83
  .ant-input,
77
84
  .ant-input-affix-wrapper {
78
85
  width: 100%;