@nokecy/qc-ui 1.1.83 → 1.1.85
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/array-table/arrayAddBtn.js +2 -1
- package/dist/cjs/array-table/cellFocusScope.d.ts +8 -7
- package/dist/cjs/array-table/cellFocusScope.js +51 -15
- package/dist/cjs/array-table/index.js +38 -21
- package/dist/cjs/array-table/indexColumn.js +2 -1
- package/dist/cjs/array-table/utils.js +27 -19
- package/dist/cjs/dialogSelect/index.less +11 -4
- package/dist/cjs/draggableModal/index.js +67 -29
- package/dist/cjs/draggableModal/style.less +6 -1
- package/dist/esm/array-table/arrayAddBtn.js +2 -1
- package/dist/esm/array-table/cellFocusScope.d.ts +8 -7
- package/dist/esm/array-table/cellFocusScope.js +52 -16
- package/dist/esm/array-table/index.js +38 -21
- package/dist/esm/array-table/indexColumn.js +2 -1
- package/dist/esm/array-table/utils.js +27 -20
- package/dist/esm/dialogSelect/index.less +11 -4
- package/dist/esm/draggableModal/index.js +67 -29
- package/dist/esm/draggableModal/style.less +6 -1
- package/dist/umd/qc-ui.min.css +1 -1
- package/dist/umd/qc-ui.min.js +1 -1
- package/package.json +1 -1
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import React, { useEffect, useRef } from 'react';
|
|
1
|
+
import React, { useCallback, useEffect, useRef } from 'react';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* 判断「焦点离开了这个单元格」的作用域,给懒挂载格「用完卸回纯文本」用。
|
|
5
5
|
*
|
|
6
|
-
* 用 React 合成的 onFocus/onBlur
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* 用 React 合成的 onFocus/onBlur 判断焦点变化:合成事件会沿 React 树冒泡,穿过 portal。
|
|
7
|
+
* 下拉面板、日期面板、选择对话框这类渲染到 body 上的弹层,焦点进去时对本格仍是「格内」。
|
|
8
|
+
* 同时监听指针离开:点击到不可聚焦的文本格或页面空白不会触发 blur,需要按点击位置恢复展示态;
|
|
9
|
+
* portal 内的指针事件仍沿 React 树到达本作用域,不会被当作离开。
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
* blur 之后紧跟着 focus
|
|
12
|
-
* (
|
|
11
|
+
* 离开不立刻判定,而是推到下一个任务再看:焦点从输入框换到格内别的元素(或弹层)时,
|
|
12
|
+
* blur 之后紧跟着 focus,后者会作废这次判定。单纯 blur 时若 activeElement 仍在格内
|
|
13
|
+
* (如窗口切走),不算离开;指针明确点击到作用域外则按离开处理。
|
|
13
14
|
*
|
|
14
15
|
* 用 display: contents,不产生盒子,不改变单元格里原有的布局。
|
|
15
16
|
*
|
|
@@ -21,34 +22,69 @@ export var CellFocusScope = function CellFocusScope(_ref) {
|
|
|
21
22
|
children = _ref.children;
|
|
22
23
|
var rootRef = useRef(null);
|
|
23
24
|
var timerRef = useRef();
|
|
25
|
+
// 通过 React portal 渲染到 body 的弹层仍属于当前格;记录经过本作用域的指针事件,
|
|
26
|
+
// 避免日期/下拉弹层中的点击被 document 级离开检测误判。@author nokecy
|
|
27
|
+
var pointerEventsInScopeRef = useRef(new WeakSet());
|
|
28
|
+
var focusWithinRef = useRef(false);
|
|
24
29
|
// 每次焦点回到格内、或卸载时递增;进行中的异步判定拿它判断自己是否已过期
|
|
25
30
|
var generationRef = useRef(0);
|
|
26
31
|
var onLeaveRef = useRef(onLeave);
|
|
27
32
|
onLeaveRef.current = onLeave;
|
|
28
|
-
var cancel = function
|
|
33
|
+
var cancel = useCallback(function () {
|
|
29
34
|
generationRef.current += 1;
|
|
30
35
|
window.clearTimeout(timerRef.current);
|
|
31
|
-
};
|
|
32
|
-
useEffect(function () {
|
|
33
|
-
return cancel;
|
|
34
36
|
}, []);
|
|
35
|
-
var
|
|
37
|
+
var scheduleLeave = useCallback(function () {
|
|
38
|
+
var pointerLeftScope = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
39
|
+
var hadFocus = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : focusWithinRef.current;
|
|
36
40
|
cancel();
|
|
37
41
|
var generation = generationRef.current;
|
|
38
42
|
timerRef.current = window.setTimeout(function () {
|
|
39
43
|
var _rootRef$current;
|
|
40
|
-
|
|
44
|
+
// blur 后 activeElement 仍在本格通常是窗口切走或格内弹层切焦点,不算离开。
|
|
45
|
+
// 指针明确点到本格/其弹层之外时,即使目标不可聚焦导致 activeElement 没变,也应离开。
|
|
46
|
+
if (!pointerLeftScope && (_rootRef$current = rootRef.current) !== null && _rootRef$current !== void 0 && _rootRef$current.contains(document.activeElement)) return;
|
|
41
47
|
onLeaveRef.current(function () {
|
|
42
48
|
return generation !== generationRef.current;
|
|
43
|
-
});
|
|
49
|
+
}, hadFocus);
|
|
44
50
|
}, 0);
|
|
51
|
+
}, [cancel]);
|
|
52
|
+
var handleFocus = function handleFocus() {
|
|
53
|
+
focusWithinRef.current = true;
|
|
54
|
+
cancel();
|
|
45
55
|
};
|
|
56
|
+
var handleBlur = function handleBlur() {
|
|
57
|
+
var hadFocus = focusWithinRef.current;
|
|
58
|
+
focusWithinRef.current = false;
|
|
59
|
+
scheduleLeave(false, hadFocus);
|
|
60
|
+
};
|
|
61
|
+
var handlePointerDownCapture = function handlePointerDownCapture(event) {
|
|
62
|
+
pointerEventsInScopeRef.current.add(event.nativeEvent);
|
|
63
|
+
};
|
|
64
|
+
useEffect(function () {
|
|
65
|
+
var handleDocumentPointerDown = function handleDocumentPointerDown(event) {
|
|
66
|
+
var root = rootRef.current;
|
|
67
|
+
if (!root) return;
|
|
68
|
+
var target = event.target;
|
|
69
|
+
// DOM 内点击以及 React portal 子树内点击都属于当前格的交互。
|
|
70
|
+
if (target instanceof Node && root.contains(target) || pointerEventsInScopeRef.current.has(event)) return;
|
|
71
|
+
// 新增行的必填空格也会预先挂载控件,但可能从未获得焦点;同样需要响应离开,
|
|
72
|
+
// 由 onLeave 根据 hadFocus 决定是否校验未触碰的空必填格。@author nokecy
|
|
73
|
+
scheduleLeave(true, focusWithinRef.current);
|
|
74
|
+
};
|
|
75
|
+
document.addEventListener('pointerdown', handleDocumentPointerDown);
|
|
76
|
+
return function () {
|
|
77
|
+
document.removeEventListener('pointerdown', handleDocumentPointerDown);
|
|
78
|
+
cancel();
|
|
79
|
+
};
|
|
80
|
+
}, [cancel, scheduleLeave]);
|
|
46
81
|
return /*#__PURE__*/React.createElement("div", {
|
|
47
82
|
ref: rootRef,
|
|
48
83
|
style: {
|
|
49
84
|
display: 'contents'
|
|
50
85
|
},
|
|
51
|
-
onFocus:
|
|
52
|
-
onBlur: handleBlur
|
|
86
|
+
onFocus: handleFocus,
|
|
87
|
+
onBlur: handleBlur,
|
|
88
|
+
onPointerDownCapture: handlePointerDownCapture
|
|
53
89
|
}, children);
|
|
54
90
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
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); }
|
|
2
1
|
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); }
|
|
3
2
|
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; }
|
|
4
3
|
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; }
|
|
5
4
|
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
5
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
7
6
|
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); }
|
|
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
8
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
9
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
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); }
|
|
@@ -34,7 +34,6 @@ import { useGridSchemes } from "../ag-grid-plus";
|
|
|
34
34
|
|
|
35
35
|
//@ts-ignore
|
|
36
36
|
var ArrayTableInner = observer(function (props) {
|
|
37
|
-
var _addition$props;
|
|
38
37
|
var height = props.height,
|
|
39
38
|
gridKey = props.gridKey;
|
|
40
39
|
var arrayTableTheme = useArrayTableTheme(true);
|
|
@@ -310,21 +309,39 @@ var ArrayTableInner = observer(function (props) {
|
|
|
310
309
|
style: {
|
|
311
310
|
marginBottom: 5
|
|
312
311
|
}
|
|
313
|
-
}, addition ?
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
312
|
+
}, addition ? function (_addition$props, _additionSchema$xCom, _ref, _additionProps$title, _additionProps$method) {
|
|
313
|
+
// addition 是 RecursionField 元素;业务配置在其 schema.x-component-props 中,
|
|
314
|
+
// 不能从 React 元素的 props 直接读取,否则默认值和标题会丢失。@author nokecy
|
|
315
|
+
var additionSchema = (_addition$props = addition.props) === null || _addition$props === void 0 ? void 0 : _addition$props.schema;
|
|
316
|
+
var additionProps = (_additionSchema$xCom = additionSchema === null || additionSchema === void 0 ? void 0 : additionSchema['x-component-props']) !== null && _additionSchema$xCom !== void 0 ? _additionSchema$xCom : {};
|
|
317
|
+
var configuredDefaults = additionProps.defaultValue;
|
|
318
|
+
var rowDefaults = configuredDefaults && _typeof(configuredDefaults) === 'object' && !Array.isArray(configuredDefaults) ? configuredDefaults : {};
|
|
319
|
+
return /*#__PURE__*/React.createElement(ArrayAddBtn, _extends({}, additionProps, {
|
|
320
|
+
title: (_ref = (_additionProps$title = additionProps.title) !== null && _additionProps$title !== void 0 ? _additionProps$title : additionSchema === null || additionSchema === void 0 ? void 0 : additionSchema.title) !== null && _ref !== void 0 ? _ref : '新增'
|
|
321
|
+
// 新增行总是回到数组顺序,避免当前列排序把空白新行插到旧明细前面。
|
|
322
|
+
,
|
|
323
|
+
onAdd: function onAdd(index) {
|
|
324
|
+
var _apiRef$current;
|
|
325
|
+
setIsAdd(true);
|
|
326
|
+
(_apiRef$current = apiRef.current) === null || _apiRef$current === void 0 || _apiRef$current.applyColumnState({
|
|
327
|
+
defaultState: {
|
|
328
|
+
sort: null,
|
|
329
|
+
sortIndex: null
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
if (typeof additionProps.onAdd === 'function') additionProps.onAdd(index);
|
|
333
|
+
}
|
|
334
|
+
// 框架属性在业务配置之后设置;新行默认追加到明细末尾。@author nokecy
|
|
335
|
+
,
|
|
336
|
+
method: (_additionProps$method = additionProps.method) !== null && _additionProps$method !== void 0 ? _additionProps$method : 'push',
|
|
337
|
+
arrayField: field,
|
|
338
|
+
schema: schema,
|
|
339
|
+
defaultValue: _objectSpread({
|
|
340
|
+
_id: uniqueId(),
|
|
341
|
+
_isNew: true
|
|
342
|
+
}, rowDefaults)
|
|
343
|
+
}));
|
|
344
|
+
}() : null, actions.map(function (column, key) {
|
|
328
345
|
return /*#__PURE__*/React.createElement(RecursionField, {
|
|
329
346
|
schema: column.schema,
|
|
330
347
|
name: key,
|
|
@@ -389,8 +406,8 @@ var ArrayTableInner = observer(function (props) {
|
|
|
389
406
|
});
|
|
390
407
|
}
|
|
391
408
|
if (isAdd) {
|
|
392
|
-
var _apiRef$
|
|
393
|
-
(_apiRef$
|
|
409
|
+
var _apiRef$current2;
|
|
410
|
+
(_apiRef$current2 = apiRef.current) === null || _apiRef$current2 === void 0 || _apiRef$current2.ensureIndexVisible(dataSource.length - 1, "bottom");
|
|
394
411
|
setIsAdd(false);
|
|
395
412
|
}
|
|
396
413
|
},
|
|
@@ -412,9 +429,9 @@ var ArrayTableInner = observer(function (props) {
|
|
|
412
429
|
' <span data-ref="eSortAsc" class="ag-header-icon ag-sort-ascending-icon"></span>' + ' <span data-ref="eSortDesc" class="ag-header-icon ag-sort-descending-icon"></span>' + ' <span data-ref="eSortNone" class="ag-header-icon ag-sort-none-icon"></span>' + " </div>" + "</div>"
|
|
413
430
|
}
|
|
414
431
|
},
|
|
415
|
-
getRowId: function getRowId(
|
|
432
|
+
getRowId: function getRowId(_ref2) {
|
|
416
433
|
var _data$_id;
|
|
417
|
-
var data =
|
|
434
|
+
var data = _ref2.data;
|
|
418
435
|
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;
|
|
419
436
|
if (id != null) return String(id);
|
|
420
437
|
// 既无 _id 也无 id 的外部数据:按对象引用从 WeakMap 取/分配稳定 id。
|
|
@@ -6,7 +6,8 @@ var containsIndexComponent = function containsIndexComponent(schema) {
|
|
|
6
6
|
var _schema$properties;
|
|
7
7
|
if (!schema) return false;
|
|
8
8
|
var component = schema['x-component'];
|
|
9
|
-
|
|
9
|
+
// ArrayTable.Index / ArrayBase.Index,以及业务常用的 ArrayTableIndex(还会把行号写进数据字段)
|
|
10
|
+
if (typeof component === 'string' && /(?:^|\.)(?:Array(?:Table)?)?Index$/.test(component)) return true;
|
|
10
11
|
return Object.values((_schema$properties = schema.properties) !== null && _schema$properties !== void 0 ? _schema$properties : {}).some(containsIndexComponent);
|
|
11
12
|
};
|
|
12
13
|
|
|
@@ -376,52 +376,60 @@ var LazyAgField = function LazyAgField(params) {
|
|
|
376
376
|
// 内层字段名:Column key 与它可能不一致(设计器形态),取值/找字段节点都按它
|
|
377
377
|
var dataKey = (_fieldSchema$name = fieldSchema === null || fieldSchema === void 0 ? void 0 : fieldSchema.name) !== null && _fieldSchema$name !== void 0 ? _fieldSchema$name : colDef === null || colDef === void 0 ? void 0 : colDef.field;
|
|
378
378
|
|
|
379
|
-
/**
|
|
379
|
+
/** 离开本格:校验通过才卸回懒挂载文本。未触碰的空必填格保留控件等待填写。@author nokecy */
|
|
380
380
|
var handleLeave = /*#__PURE__*/function () {
|
|
381
|
-
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(isStale) {
|
|
381
|
+
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(isStale, hadFocus) {
|
|
382
382
|
var _field$value$indexOf3, _field$value3, _field$value3$indexOf, _field$form;
|
|
383
|
-
var index, cellField;
|
|
383
|
+
var currentValue, index, cellField;
|
|
384
384
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
385
385
|
while (1) switch (_context.prev = _context.next) {
|
|
386
386
|
case 0:
|
|
387
|
+
currentValue = dataKey != null ? readByFieldPath(record, dataKey) : value; // 新增行的必填空格会预先挂载以参与提交校验;若用户从未进入该格,不在点击页面其他位置时
|
|
388
|
+
// 主动触发校验,但已带值的格子仍可恢复静默文本态。@author nokecy
|
|
389
|
+
if (!(required && isBlank(currentValue) && !hadFocus)) {
|
|
390
|
+
_context.next = 3;
|
|
391
|
+
break;
|
|
392
|
+
}
|
|
393
|
+
return _context.abrupt("return");
|
|
394
|
+
case 3:
|
|
387
395
|
index = (_field$value$indexOf3 = field === null || field === void 0 || (_field$value3 = field.value) === null || _field$value3 === void 0 || (_field$value3$indexOf = _field$value3.indexOf) === null || _field$value3$indexOf === void 0 ? void 0 : _field$value3$indexOf.call(_field$value3, record)) !== null && _field$value$indexOf3 !== void 0 ? _field$value$indexOf3 : -1; // 字段节点按数据路径找(不含 void 容器);从没挂载过就没有节点,无需校验
|
|
388
396
|
cellField = index >= 0 && dataKey ? (_field$form = field.form) === null || _field$form === void 0 ? void 0 : _field$form.query(field.path.concat(index).concat(dataKey)).take() : undefined;
|
|
389
397
|
if (!cellField) {
|
|
390
|
-
_context.next =
|
|
398
|
+
_context.next = 14;
|
|
391
399
|
break;
|
|
392
400
|
}
|
|
393
|
-
_context.prev =
|
|
394
|
-
_context.next =
|
|
401
|
+
_context.prev = 6;
|
|
402
|
+
_context.next = 9;
|
|
395
403
|
return cellField.validate();
|
|
396
|
-
case
|
|
397
|
-
_context.next =
|
|
404
|
+
case 9:
|
|
405
|
+
_context.next = 14;
|
|
398
406
|
break;
|
|
399
|
-
case 8:
|
|
400
|
-
_context.prev = 8;
|
|
401
|
-
_context.t0 = _context["catch"](3);
|
|
402
|
-
return _context.abrupt("return");
|
|
403
407
|
case 11:
|
|
408
|
+
_context.prev = 11;
|
|
409
|
+
_context.t0 = _context["catch"](6);
|
|
410
|
+
return _context.abrupt("return");
|
|
411
|
+
case 14:
|
|
404
412
|
if (!isStale()) {
|
|
405
|
-
_context.next =
|
|
413
|
+
_context.next = 16;
|
|
406
414
|
break;
|
|
407
415
|
}
|
|
408
416
|
return _context.abrupt("return");
|
|
409
|
-
case
|
|
417
|
+
case 16:
|
|
410
418
|
if (!(required && isBlank(dataKey != null ? readByFieldPath(record, dataKey) : undefined))) {
|
|
411
|
-
_context.next =
|
|
419
|
+
_context.next = 18;
|
|
412
420
|
break;
|
|
413
421
|
}
|
|
414
422
|
return _context.abrupt("return");
|
|
415
|
-
case
|
|
423
|
+
case 18:
|
|
416
424
|
activeCells.delete(key);
|
|
417
425
|
rerender();
|
|
418
|
-
case
|
|
426
|
+
case 20:
|
|
419
427
|
case "end":
|
|
420
428
|
return _context.stop();
|
|
421
429
|
}
|
|
422
|
-
}, _callee, null, [[
|
|
430
|
+
}, _callee, null, [[6, 11]]);
|
|
423
431
|
}));
|
|
424
|
-
return function handleLeave(_x) {
|
|
432
|
+
return function handleLeave(_x, _x2) {
|
|
425
433
|
return _ref5.apply(this, arguments);
|
|
426
434
|
};
|
|
427
435
|
}();
|
|
@@ -794,7 +802,6 @@ var useAddition = function useAddition() {
|
|
|
794
802
|
}, null);
|
|
795
803
|
};
|
|
796
804
|
export { isColumnComponent, useArrayTableSources, useArrayTableActions, buildArrayTableColumns, useAddition, LazyAgField, LazyReadOnlyText };
|
|
797
|
-
|
|
798
805
|
/** 简单字段名(非路径、非解构),默认值回填只处理这一种 */
|
|
799
806
|
var SIMPLE_FIELD_NAME = /^[A-Za-z_$][\w$]*$/;
|
|
800
807
|
/**
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
display: inline-flex;
|
|
8
8
|
align-items: center;
|
|
9
9
|
justify-content: center;
|
|
10
|
-
width:
|
|
11
|
-
height:
|
|
10
|
+
width: 24px;
|
|
11
|
+
height: 24px;
|
|
12
|
+
font-size: 16px;
|
|
12
13
|
cursor: pointer;
|
|
13
14
|
pointer-events: auto;
|
|
14
15
|
color: var(--qc-dialog-select-trigger-color, rgba(0, 0, 0, 0.45));
|
|
@@ -19,18 +20,24 @@
|
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
// 为放大后的入口预留文本空间,避免选中值与图标重叠。
|
|
24
|
+
&.ant-select-single:not(.ant-select-allow-clear) .ant-select-selection-item,
|
|
25
|
+
&.ant-select-single:not(.ant-select-allow-clear) .ant-select-selection-placeholder {
|
|
26
|
+
padding-inline-end: 24px;
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
// 悬停时 antd 会把后缀淡出、换成清除图标;这里让入口始终可见,清除图标左移一格并排。
|
|
23
30
|
&.ant-select.ant-select:hover .ant-select-arrow:not(:last-child) {
|
|
24
31
|
opacity: 1;
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
&.ant-select-allow-clear .ant-select-clear {
|
|
28
|
-
inset-inline-end:
|
|
35
|
+
inset-inline-end: 37px;
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
&.ant-select-allow-clear .ant-select-selection-item,
|
|
32
39
|
&.ant-select-allow-clear .ant-select-selection-placeholder {
|
|
33
|
-
padding-inline-end:
|
|
40
|
+
padding-inline-end: 42px;
|
|
34
41
|
}
|
|
35
42
|
|
|
36
43
|
&.ant-select-multiple .ant-select-selector {
|
|
@@ -39,24 +39,31 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
39
39
|
_useState6 = _slicedToArray(_useState5, 2),
|
|
40
40
|
isResizing = _useState6[0],
|
|
41
41
|
setIsResizing = _useState6[1];
|
|
42
|
-
var _useState7 = useState(
|
|
43
|
-
_useState8 = _slicedToArray(_useState7, 2),
|
|
44
|
-
resizeDirection = _useState8[0],
|
|
45
|
-
setResizeDirection = _useState8[1];
|
|
46
|
-
var _useState9 = useState({
|
|
42
|
+
var _useState7 = useState({
|
|
47
43
|
width: 0,
|
|
48
44
|
height: 0
|
|
49
45
|
}),
|
|
50
|
-
|
|
51
|
-
modalSize =
|
|
52
|
-
setModalSize =
|
|
53
|
-
var
|
|
46
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
47
|
+
modalSize = _useState8[0],
|
|
48
|
+
setModalSize = _useState8[1];
|
|
49
|
+
var _useState9 = useState({
|
|
54
50
|
x: 0,
|
|
55
51
|
y: 0
|
|
56
52
|
}),
|
|
53
|
+
_useState10 = _slicedToArray(_useState9, 2),
|
|
54
|
+
modalPosition = _useState10[0],
|
|
55
|
+
setModalPosition = _useState10[1];
|
|
56
|
+
var _useState11 = useState(false),
|
|
57
57
|
_useState12 = _slicedToArray(_useState11, 2),
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
hasResized = _useState12[0],
|
|
59
|
+
setHasResized = _useState12[1];
|
|
60
|
+
var _useState13 = useState({
|
|
61
|
+
x: 0,
|
|
62
|
+
y: 0
|
|
63
|
+
}),
|
|
64
|
+
_useState14 = _slicedToArray(_useState13, 2),
|
|
65
|
+
dragPosition = _useState14[0],
|
|
66
|
+
setDragPosition = _useState14[1];
|
|
60
67
|
|
|
61
68
|
// 解构 props,分离出 wrapClassName 和 open
|
|
62
69
|
var propsWrapClassName = props.wrapClassName,
|
|
@@ -80,6 +87,25 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
80
87
|
if (timer !== undefined) clearTimeout(timer);
|
|
81
88
|
};
|
|
82
89
|
}, [open]);
|
|
90
|
+
|
|
91
|
+
// 每次关闭后还原弹窗定位;下次打开仍按调用方传入的默认尺寸居中显示。@author nokecy
|
|
92
|
+
useEffect(function () {
|
|
93
|
+
if (open) return;
|
|
94
|
+
setIsResizing(false);
|
|
95
|
+
setHasResized(false);
|
|
96
|
+
setModalSize({
|
|
97
|
+
width: 0,
|
|
98
|
+
height: 0
|
|
99
|
+
});
|
|
100
|
+
setModalPosition({
|
|
101
|
+
x: 0,
|
|
102
|
+
y: 0
|
|
103
|
+
});
|
|
104
|
+
setDragPosition({
|
|
105
|
+
x: 0,
|
|
106
|
+
y: 0
|
|
107
|
+
});
|
|
108
|
+
}, [open]);
|
|
83
109
|
var _onStart = function onStart(_event, uiData) {
|
|
84
110
|
var _draggleRef$current;
|
|
85
111
|
var _window$document$docu = window.document.documentElement,
|
|
@@ -117,7 +143,12 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
117
143
|
x: rect.left,
|
|
118
144
|
y: rect.top
|
|
119
145
|
});
|
|
120
|
-
|
|
146
|
+
setHasResized(true);
|
|
147
|
+
// 将当前视觉位置作为新定位基点,避免弹窗自身和 react-draggable 位移重复叠加。@author nokecy
|
|
148
|
+
setDragPosition({
|
|
149
|
+
x: 0,
|
|
150
|
+
y: 0
|
|
151
|
+
});
|
|
121
152
|
setIsResizing(true);
|
|
122
153
|
var startX = e.clientX;
|
|
123
154
|
var startY = e.clientY;
|
|
@@ -130,30 +161,28 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
130
161
|
var deltaY = moveEvent.clientY - startY;
|
|
131
162
|
var newWidth = startWidth;
|
|
132
163
|
var newHeight = startHeight;
|
|
133
|
-
var newLeft = startLeft;
|
|
134
|
-
var newTop = startTop;
|
|
135
164
|
|
|
136
165
|
// 根据方向计算新尺寸
|
|
137
166
|
if (direction.includes('e')) {
|
|
138
|
-
newWidth =
|
|
167
|
+
newWidth = startWidth + deltaX;
|
|
139
168
|
}
|
|
140
169
|
if (direction.includes('w')) {
|
|
141
|
-
newWidth =
|
|
142
|
-
newLeft = startLeft + (startWidth - newWidth);
|
|
170
|
+
newWidth = startWidth - deltaX;
|
|
143
171
|
}
|
|
144
172
|
if (direction.includes('s')) {
|
|
145
|
-
newHeight =
|
|
173
|
+
newHeight = startHeight + deltaY;
|
|
146
174
|
}
|
|
147
175
|
if (direction.includes('n')) {
|
|
148
|
-
newHeight =
|
|
149
|
-
newTop = startTop + (startHeight - newHeight);
|
|
176
|
+
newHeight = startHeight - deltaY;
|
|
150
177
|
}
|
|
151
178
|
|
|
152
|
-
//
|
|
179
|
+
// 限制最小与最大尺寸,再按固定边计算另一侧位置,确保拖哪条边就移动哪条边。@author nokecy
|
|
153
180
|
var maxWidth = window.innerWidth * 0.95;
|
|
154
181
|
var maxHeight = window.innerHeight * 0.95;
|
|
155
|
-
newWidth = Math.min(newWidth, maxWidth);
|
|
156
|
-
newHeight = Math.min(newHeight, maxHeight);
|
|
182
|
+
newWidth = Math.min(Math.max(400, newWidth), maxWidth);
|
|
183
|
+
newHeight = Math.min(Math.max(300, newHeight), maxHeight);
|
|
184
|
+
var newLeft = direction.includes('w') ? startLeft + startWidth - newWidth : startLeft;
|
|
185
|
+
var newTop = direction.includes('n') ? startTop + startHeight - newHeight : startTop;
|
|
157
186
|
|
|
158
187
|
// 直接更新DOM以实现实时效果
|
|
159
188
|
modal.style.width = "".concat(newWidth, "px");
|
|
@@ -182,7 +211,6 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
182
211
|
};
|
|
183
212
|
var handleMouseUp = function handleMouseUp() {
|
|
184
213
|
setIsResizing(false);
|
|
185
|
-
setResizeDirection('');
|
|
186
214
|
document.removeEventListener('mousemove', handleMouseMove);
|
|
187
215
|
document.removeEventListener('mouseup', handleMouseUp);
|
|
188
216
|
|
|
@@ -197,7 +225,8 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
197
225
|
|
|
198
226
|
// 合并类名
|
|
199
227
|
var resizingClass = isResizing ? 'modal-wrap-resizing' : '';
|
|
200
|
-
var
|
|
228
|
+
var resizedClass = hasResized ? 'modal-wrap-resized' : '';
|
|
229
|
+
var mergedWrapClassName = [propsWrapClassName, resizingClass, resizedClass].filter(Boolean).join(' ');
|
|
201
230
|
return /*#__PURE__*/React.createElement(Modal, _extends({
|
|
202
231
|
maskClosable: false,
|
|
203
232
|
width: width,
|
|
@@ -223,18 +252,27 @@ var DraggableModal = function DraggableModal(props) {
|
|
|
223
252
|
}, props.title),
|
|
224
253
|
modalRender: function modalRender(modal) {
|
|
225
254
|
return /*#__PURE__*/React.createElement(Draggable, {
|
|
226
|
-
disabled: disabled,
|
|
255
|
+
disabled: disabled || isResizing,
|
|
227
256
|
bounds: bounds,
|
|
257
|
+
position: dragPosition,
|
|
228
258
|
nodeRef: draggleRef,
|
|
229
259
|
onStart: function onStart(event, uiData) {
|
|
230
260
|
return _onStart(event, uiData);
|
|
231
261
|
},
|
|
262
|
+
onDrag: function onDrag(_event, uiData) {
|
|
263
|
+
return setDragPosition({
|
|
264
|
+
x: uiData.x,
|
|
265
|
+
y: uiData.y
|
|
266
|
+
});
|
|
267
|
+
},
|
|
232
268
|
cancel: ".resize-handle"
|
|
233
269
|
}, /*#__PURE__*/React.createElement("div", {
|
|
234
270
|
ref: draggleRef,
|
|
235
|
-
style:
|
|
236
|
-
position: '
|
|
237
|
-
|
|
271
|
+
style: hasResized && modalSize.width > 0 ? {
|
|
272
|
+
position: 'fixed',
|
|
273
|
+
left: modalPosition.x,
|
|
274
|
+
top: modalPosition.y,
|
|
275
|
+
height: "".concat(modalSize.height, "px"),
|
|
238
276
|
width: "".concat(modalSize.width, "px"),
|
|
239
277
|
'--modal-width': "".concat(modalSize.width, "px"),
|
|
240
278
|
'--modal-height': "".concat(modalSize.height, "px")
|