@creekjs/web-components 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.fatherrc.ts +13 -0
- package/.turbo/daemon/deec863de02760ed-turbo.log.2024-11-20 +0 -0
- package/README.md +1026 -0
- package/dist/bg-center/index.js +28 -0
- package/dist/creek-config-provider/CreekConfigContext.js +2 -0
- package/dist/creek-config-provider/index.js +14 -0
- package/dist/creek-hooks/index.js +1 -0
- package/dist/creek-hooks/useViewportHeight.js +147 -0
- package/dist/creek-icon/index.js +37 -0
- package/dist/creek-keep-alive/index.js +20 -0
- package/dist/creek-layout/CollapseButton.js +59 -0
- package/dist/creek-layout/Exception/NotFound.js +13 -0
- package/dist/creek-layout/Exception/NotFoundPage.js +5 -0
- package/dist/creek-layout/Exception/index.js +8 -0
- package/dist/creek-layout/HeaderContent/FullScreen.js +50 -0
- package/dist/creek-layout/HeaderContent/UserInfo.js +58 -0
- package/dist/creek-layout/HeaderContent/index.js +33 -0
- package/dist/creek-layout/index.js +86 -0
- package/dist/creek-loading/index.js +52 -0
- package/dist/creek-search/CreekSearch.js +51 -0
- package/dist/creek-search/CreekSearchContext.js +546 -0
- package/dist/creek-search/CreekSearchFilterDisplay.js +97 -0
- package/dist/creek-search/CreekSearchInput.js +96 -0
- package/dist/creek-search/CreekSearchValueSelector.js +422 -0
- package/dist/creek-search/index.js +5 -0
- package/dist/creek-search/type.js +1 -0
- package/dist/creek-table/SearchTable.js +121 -0
- package/dist/creek-table/TableOptionRender.js +65 -0
- package/dist/creek-table/TableViewContent.js +45 -0
- package/dist/creek-table/hooks/index.js +3 -0
- package/dist/creek-table/hooks/useAdaptiveToolBar.js +48 -0
- package/dist/creek-table/hooks/useAutoAddFilterToColumns.js +93 -0
- package/dist/creek-table/hooks/useElementDistance.js +58 -0
- package/dist/creek-table/index.js +25 -0
- package/dist/creek-table/toolBarRender.js +36 -0
- package/dist/creek-table/type.js +1 -0
- package/dist/index.js +7 -0
- package/package.json +19 -0
- package/src/bg-center/index.tsx +26 -0
- package/src/creek-config-provider/CreekConfigContext.tsx +7 -0
- package/src/creek-config-provider/index.tsx +12 -0
- package/src/creek-hooks/index.ts +1 -0
- package/src/creek-hooks/useViewportHeight.tsx +154 -0
- package/src/creek-icon/index.tsx +34 -0
- package/src/creek-keep-alive/index.tsx +11 -0
- package/src/creek-layout/CollapseButton.tsx +66 -0
- package/src/creek-layout/Exception/NotFound.tsx +12 -0
- package/src/creek-layout/Exception/NotFoundPage.tsx +4 -0
- package/src/creek-layout/Exception/index.tsx +10 -0
- package/src/creek-layout/HeaderContent/FullScreen.tsx +46 -0
- package/src/creek-layout/HeaderContent/UserInfo.tsx +54 -0
- package/src/creek-layout/HeaderContent/index.tsx +27 -0
- package/src/creek-layout/index.tsx +98 -0
- package/src/creek-loading/index.tsx +35 -0
- package/src/creek-search/CreekSearch.tsx +59 -0
- package/src/creek-search/CreekSearchContext.tsx +593 -0
- package/src/creek-search/CreekSearchFilterDisplay.tsx +84 -0
- package/src/creek-search/CreekSearchInput.tsx +75 -0
- package/src/creek-search/CreekSearchValueSelector.tsx +324 -0
- package/src/creek-search/index.tsx +5 -0
- package/src/creek-search/type.ts +9 -0
- package/src/creek-table/SearchTable.tsx +115 -0
- package/src/creek-table/TableOptionRender.tsx +57 -0
- package/src/creek-table/TableViewContent.tsx +44 -0
- package/src/creek-table/hooks/index.ts +4 -0
- package/src/creek-table/hooks/useAdaptiveToolBar.tsx +45 -0
- package/src/creek-table/hooks/useAutoAddFilterToColumns.tsx +90 -0
- package/src/creek-table/hooks/useElementDistance.tsx +64 -0
- package/src/creek-table/index.tsx +16 -0
- package/src/creek-table/toolBarRender.tsx +28 -0
- package/src/creek-table/type.ts +21 -0
- package/src/index.tsx +8 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
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."); }
|
|
3
|
+
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); }
|
|
4
|
+
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; }
|
|
5
|
+
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; } }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
+
import { ExportOutlined, ImportOutlined } from '@ant-design/icons';
|
|
8
|
+
import { Space, Tooltip } from 'antd';
|
|
9
|
+
import { createStyles } from 'antd-style';
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
+
var useStyles = createStyles(function (_ref) {
|
|
13
|
+
var prefixCls = _ref.prefixCls,
|
|
14
|
+
token = _ref.token;
|
|
15
|
+
return {
|
|
16
|
+
'table-option-render-item': {
|
|
17
|
+
border: "1px solid ".concat(token.colorBorder),
|
|
18
|
+
borderRadius: token.borderRadius,
|
|
19
|
+
padding: '8px',
|
|
20
|
+
cursor: 'pointer'
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
export var TableOptionRender = function TableOptionRender(props) {
|
|
25
|
+
var defaultDom = props.defaultDom,
|
|
26
|
+
importConfig = props.importConfig,
|
|
27
|
+
exportConfig = props.exportConfig;
|
|
28
|
+
var _useStyles = useStyles(),
|
|
29
|
+
styles = _useStyles.styles;
|
|
30
|
+
var _ref2 = defaultDom || [],
|
|
31
|
+
_ref3 = _slicedToArray(_ref2, 3),
|
|
32
|
+
reload = _ref3[0],
|
|
33
|
+
dis = _ref3[1],
|
|
34
|
+
setting = _ref3[2];
|
|
35
|
+
return /*#__PURE__*/_jsxs(Space, {
|
|
36
|
+
size: 8,
|
|
37
|
+
children: [importConfig && /*#__PURE__*/_jsx("span", {
|
|
38
|
+
className: styles['table-option-render-item'],
|
|
39
|
+
onClick: function onClick() {
|
|
40
|
+
var _importConfig$onClick;
|
|
41
|
+
(_importConfig$onClick = importConfig.onClick) === null || _importConfig$onClick === void 0 || _importConfig$onClick.call(importConfig);
|
|
42
|
+
},
|
|
43
|
+
children: /*#__PURE__*/_jsx(Tooltip, {
|
|
44
|
+
title: importConfig.text || '导入',
|
|
45
|
+
children: importConfig.icon || /*#__PURE__*/_jsx(ImportOutlined, {})
|
|
46
|
+
})
|
|
47
|
+
}), exportConfig && /*#__PURE__*/_jsx("span", {
|
|
48
|
+
className: styles['table-option-render-item'],
|
|
49
|
+
onClick: function onClick() {
|
|
50
|
+
var _exportConfig$onClick;
|
|
51
|
+
(_exportConfig$onClick = exportConfig.onClick) === null || _exportConfig$onClick === void 0 || _exportConfig$onClick.call(exportConfig);
|
|
52
|
+
},
|
|
53
|
+
children: /*#__PURE__*/_jsx(Tooltip, {
|
|
54
|
+
title: exportConfig.text || '导出',
|
|
55
|
+
children: exportConfig.icon || /*#__PURE__*/_jsx(ExportOutlined, {})
|
|
56
|
+
})
|
|
57
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
58
|
+
className: styles['table-option-render-item'],
|
|
59
|
+
children: reload
|
|
60
|
+
}), /*#__PURE__*/_jsx("span", {
|
|
61
|
+
className: styles['table-option-render-item'],
|
|
62
|
+
children: setting
|
|
63
|
+
})]
|
|
64
|
+
});
|
|
65
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useDebounceFn, useDeepCompareEffect } from 'ahooks';
|
|
2
|
+
import { useViewportHeight } from "../creek-hooks";
|
|
3
|
+
import { CreekFilterDisplay } from "../creek-search";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
6
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
// 独立的 TableViewWrapper 组件 - 包含所有表格视图相关逻辑
|
|
8
|
+
export var TableViewContent = function TableViewContent(props) {
|
|
9
|
+
var prefixCls = props.prefixCls,
|
|
10
|
+
pageFixedBottomConfig = props.pageFixedBottomConfig,
|
|
11
|
+
pageFixedBottom = props.pageFixedBottom,
|
|
12
|
+
children = props.children;
|
|
13
|
+
var _useViewportHeight = useViewportHeight({
|
|
14
|
+
isObserverParent: true
|
|
15
|
+
}),
|
|
16
|
+
containerRef = _useViewportHeight.containerRef,
|
|
17
|
+
viewPortHeight = _useViewportHeight.viewPortHeight;
|
|
18
|
+
|
|
19
|
+
// 设置antd内容区的高度,使得分页永远在底部
|
|
20
|
+
var _useDebounceFn = useDebounceFn(function (mainHeight) {
|
|
21
|
+
var _containerRef$current, _containerRef$current2;
|
|
22
|
+
var antdTableContentElement = (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.querySelector(".".concat(prefixCls, "-table"));
|
|
23
|
+
var antdPaginationElement = (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.querySelector(".".concat(prefixCls, "-pagination"));
|
|
24
|
+
if (antdTableContentElement) {
|
|
25
|
+
var paginationHeight = (antdPaginationElement === null || antdPaginationElement === void 0 ? void 0 : antdPaginationElement.clientHeight) || 0;
|
|
26
|
+
var bottomFix = (pageFixedBottomConfig === null || pageFixedBottomConfig === void 0 ? void 0 : pageFixedBottomConfig.bottomFix) || 8;
|
|
27
|
+
var tableContentHeight = mainHeight - paginationHeight - 16 - bottomFix;
|
|
28
|
+
antdTableContentElement.setAttribute('style', "height: ".concat(tableContentHeight, "px"));
|
|
29
|
+
}
|
|
30
|
+
}),
|
|
31
|
+
setAntdTableContentHeight = _useDebounceFn.run;
|
|
32
|
+
useDeepCompareEffect(function () {
|
|
33
|
+
if (pageFixedBottom) {
|
|
34
|
+
setAntdTableContentHeight(viewPortHeight !== null && viewPortHeight !== void 0 ? viewPortHeight : 0);
|
|
35
|
+
}
|
|
36
|
+
}, [viewPortHeight, pageFixedBottom, setAntdTableContentHeight]);
|
|
37
|
+
|
|
38
|
+
// 默认渲染逻辑
|
|
39
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
40
|
+
children: [/*#__PURE__*/_jsx(CreekFilterDisplay, {}), /*#__PURE__*/_jsx("div", {
|
|
41
|
+
ref: containerRef,
|
|
42
|
+
children: children
|
|
43
|
+
})]
|
|
44
|
+
});
|
|
45
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
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."); }
|
|
3
|
+
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); }
|
|
4
|
+
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; }
|
|
5
|
+
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; } }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
+
import { useEffect, useRef, useState } from 'react';
|
|
8
|
+
import { useElementDistance } from "./useElementDistance";
|
|
9
|
+
export var useAdaptiveToolBar = function useAdaptiveToolBar(options) {
|
|
10
|
+
var element1Ref = useRef(null);
|
|
11
|
+
var element2Ref = useRef(null);
|
|
12
|
+
var _useState = useState(false),
|
|
13
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
14
|
+
shouldCollapse = _useState2[0],
|
|
15
|
+
setShouldCollapse = _useState2[1];
|
|
16
|
+
var containerRef = options.containerRef,
|
|
17
|
+
prefixCls = options.prefixCls,
|
|
18
|
+
_options$minLeftDista = options.minLeftDistance,
|
|
19
|
+
minLeftDistance = _options$minLeftDista === void 0 ? 48 : _options$minLeftDista,
|
|
20
|
+
_options$hysteresis = options.hysteresis,
|
|
21
|
+
hysteresis = _options$hysteresis === void 0 ? 36 : _options$hysteresis;
|
|
22
|
+
useEffect(function () {
|
|
23
|
+
var _containerRef$current, _containerRef$current2;
|
|
24
|
+
element1Ref.current = (containerRef === null || containerRef === void 0 || (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.querySelector(".".concat(prefixCls, "-pro-table-list-toolbar-left"))) || null;
|
|
25
|
+
element2Ref.current = (containerRef === null || containerRef === void 0 || (_containerRef$current2 = containerRef.current) === null || _containerRef$current2 === void 0 || (_containerRef$current2 = _containerRef$current2.querySelector(".".concat(prefixCls, "-pro-table-list-toolbar-right"))) === null || _containerRef$current2 === void 0 ? void 0 : _containerRef$current2.querySelector('div')) || null;
|
|
26
|
+
});
|
|
27
|
+
var distance = useElementDistance(element1Ref, element2Ref);
|
|
28
|
+
|
|
29
|
+
// 方案一:使用滞回逻辑防止震荡
|
|
30
|
+
useEffect(function () {
|
|
31
|
+
if (!(distance !== null && distance !== void 0 && distance.x)) return;
|
|
32
|
+
var currentDistance = distance.x;
|
|
33
|
+
if (shouldCollapse) {
|
|
34
|
+
// 当前是折叠状态,需要距离足够大才展开
|
|
35
|
+
if (currentDistance > minLeftDistance + hysteresis) {
|
|
36
|
+
setShouldCollapse(false);
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
// 当前是展开状态,距离小于阈值时折叠
|
|
40
|
+
if (currentDistance < minLeftDistance) {
|
|
41
|
+
setShouldCollapse(true);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}, [distance === null || distance === void 0 ? void 0 : distance.x, minLeftDistance, hysteresis, shouldCollapse]);
|
|
45
|
+
return {
|
|
46
|
+
shouldCollapse: shouldCollapse
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
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
|
+
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; }
|
|
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; }
|
|
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; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
8
|
+
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."); }
|
|
9
|
+
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); }
|
|
10
|
+
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; }
|
|
11
|
+
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; } }
|
|
12
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
13
|
+
import { useMemoizedFn, useSafeState } from 'ahooks';
|
|
14
|
+
import { useMemo } from 'react';
|
|
15
|
+
import { CreekSearchValueSelector, useSearchContext } from "../../creek-search";
|
|
16
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
|
+
export var useAutoAddFilterToColumns = function useAutoAddFilterToColumns(_ref) {
|
|
18
|
+
var columns = _ref.columns,
|
|
19
|
+
autoAddFilterForColumn = _ref.autoAddFilterForColumn;
|
|
20
|
+
var _useSearchContext = useSearchContext(),
|
|
21
|
+
hasOptions = _useSearchContext.hasOptions,
|
|
22
|
+
setSelectedColumn = _useSearchContext.setSelectedColumn,
|
|
23
|
+
filters = _useSearchContext.filters;
|
|
24
|
+
|
|
25
|
+
// 管理每列的下拉框状态
|
|
26
|
+
var _useSafeState = useSafeState({}),
|
|
27
|
+
_useSafeState2 = _slicedToArray(_useSafeState, 2),
|
|
28
|
+
filterOpenMap = _useSafeState2[0],
|
|
29
|
+
setFilterOpenMap = _useSafeState2[1];
|
|
30
|
+
|
|
31
|
+
// 获取列的唯一标识
|
|
32
|
+
var getColumnKey = useMemoizedFn(function (column) {
|
|
33
|
+
return column.dataIndex;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// 控制特定列的下拉框开关
|
|
37
|
+
var setColumnFilterOpen = useMemoizedFn(function (columnKey, open) {
|
|
38
|
+
setFilterOpenMap(function (prev) {
|
|
39
|
+
return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, columnKey, open));
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// 关闭特定列的下拉框
|
|
44
|
+
var closeColumnFilter = useMemoizedFn(function (columnKey) {
|
|
45
|
+
setFilterOpenMap(function (prev) {
|
|
46
|
+
return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, columnKey, false));
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// 自动为列添加筛选功能
|
|
51
|
+
var autoAddFilterToColumns = useMemoizedFn(function () {
|
|
52
|
+
var columns = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
53
|
+
return columns.map(function (column) {
|
|
54
|
+
if (hasOptions(column)) {
|
|
55
|
+
var newColumn = _objectSpread({}, column);
|
|
56
|
+
var columnKey = getColumnKey(newColumn);
|
|
57
|
+
return _objectSpread(_objectSpread({}, newColumn), {}, {
|
|
58
|
+
filters: (newColumn === null || newColumn === void 0 ? void 0 : newColumn.filters) || true,
|
|
59
|
+
onFilter: (newColumn === null || newColumn === void 0 ? void 0 : newColumn.onFilter) || false,
|
|
60
|
+
filtered: filters.map(function (item) {
|
|
61
|
+
return item.dataIndex;
|
|
62
|
+
}).includes(columnKey),
|
|
63
|
+
filterDropdown: /*#__PURE__*/_jsx(CreekSearchValueSelector, {
|
|
64
|
+
onConfirm: function onConfirm() {
|
|
65
|
+
// 点击确认时关闭当前列的下拉框
|
|
66
|
+
closeColumnFilter(columnKey);
|
|
67
|
+
}
|
|
68
|
+
}),
|
|
69
|
+
filterDropdownProps: {
|
|
70
|
+
open: filterOpenMap[columnKey] || false,
|
|
71
|
+
onOpenChange: function onOpenChange(open) {
|
|
72
|
+
if (open) {
|
|
73
|
+
var selectedColumn = columns.find(function (item) {
|
|
74
|
+
return item.dataIndex === columnKey;
|
|
75
|
+
});
|
|
76
|
+
setSelectedColumn(selectedColumn);
|
|
77
|
+
}
|
|
78
|
+
setColumnFilterOpen(columnKey, open);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return column;
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
var columnsWithFilter = useMemo(function () {
|
|
87
|
+
return autoAddFilterForColumn ? autoAddFilterToColumns(columns) : columns;
|
|
88
|
+
}, [columns, filters, autoAddFilterToColumns, filterOpenMap]);
|
|
89
|
+
return {
|
|
90
|
+
columnsWithFilter: columnsWithFilter,
|
|
91
|
+
getColumnKey: getColumnKey
|
|
92
|
+
};
|
|
93
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
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."); }
|
|
3
|
+
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); }
|
|
4
|
+
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; }
|
|
5
|
+
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; } }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
+
import { useDebounceFn, useEventListener, useLatest } from 'ahooks';
|
|
8
|
+
import { useEffect, useState } from 'react';
|
|
9
|
+
var getElementCenter = function getElementCenter(element) {
|
|
10
|
+
var rect = element.getBoundingClientRect();
|
|
11
|
+
return {
|
|
12
|
+
left: rect.left,
|
|
13
|
+
width: rect.width
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
var calculateDistance = function calculateDistance(pos1, pos2) {
|
|
17
|
+
var x = Math.abs(pos2.left - pos1.left - pos1.width);
|
|
18
|
+
return {
|
|
19
|
+
x: x
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
export var useElementDistance = function useElementDistance(element1Ref, element2Ref) {
|
|
23
|
+
var _useState = useState(null),
|
|
24
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
25
|
+
distance = _useState2[0],
|
|
26
|
+
setDistance = _useState2[1];
|
|
27
|
+
var distanceRef = useLatest(distance);
|
|
28
|
+
var _useDebounceFn = useDebounceFn(function () {
|
|
29
|
+
if (!element1Ref.current || !element2Ref.current) {
|
|
30
|
+
if (distanceRef.current !== null) {
|
|
31
|
+
setDistance(null);
|
|
32
|
+
}
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
var pos1 = getElementCenter(element1Ref.current);
|
|
36
|
+
var pos2 = getElementCenter(element2Ref.current);
|
|
37
|
+
var newDistance = calculateDistance(pos1, pos2);
|
|
38
|
+
|
|
39
|
+
// 只有当距离发生变化时才更新,避免不必要的重渲染
|
|
40
|
+
if (!distanceRef.current || distanceRef.current.x !== newDistance.x) {
|
|
41
|
+
setDistance(newDistance);
|
|
42
|
+
}
|
|
43
|
+
}, {
|
|
44
|
+
wait: 100
|
|
45
|
+
}),
|
|
46
|
+
calculateAndUpdateDistance = _useDebounceFn.run;
|
|
47
|
+
|
|
48
|
+
// 初始计算
|
|
49
|
+
useEffect(function () {
|
|
50
|
+
calculateAndUpdateDistance();
|
|
51
|
+
}, [element1Ref, element2Ref]);
|
|
52
|
+
|
|
53
|
+
// 监听 window 的 resize 和 scroll 事件
|
|
54
|
+
useEventListener('resize', calculateAndUpdateDistance, {
|
|
55
|
+
target: window
|
|
56
|
+
});
|
|
57
|
+
return distance;
|
|
58
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
var _excluded = ["columns", "onSubmit"];
|
|
3
|
+
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
|
+
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
|
+
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
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
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 _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
9
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
10
|
+
import { CreekSearchProvider } from "../creek-search";
|
|
11
|
+
import { SearchProTable } from "./SearchTable";
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
export var CreekTable = function CreekTable(props) {
|
|
14
|
+
var _props$columns = props.columns,
|
|
15
|
+
columns = _props$columns === void 0 ? [] : _props$columns,
|
|
16
|
+
onSubmit = props.onSubmit,
|
|
17
|
+
restProps = _objectWithoutProperties(props, _excluded);
|
|
18
|
+
return /*#__PURE__*/_jsx(CreekSearchProvider, {
|
|
19
|
+
columns: columns,
|
|
20
|
+
onSubmit: onSubmit,
|
|
21
|
+
children: /*#__PURE__*/_jsx(SearchProTable, _objectSpread({
|
|
22
|
+
columns: columns
|
|
23
|
+
}, restProps))
|
|
24
|
+
});
|
|
25
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableRest(); }
|
|
2
|
+
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."); }
|
|
3
|
+
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); }
|
|
4
|
+
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; }
|
|
5
|
+
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
+
import { DownOutlined } from '@ant-design/icons';
|
|
8
|
+
import { Button, Dropdown } from 'antd';
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
export var toolBarRender = function toolBarRender(options) {
|
|
12
|
+
var _restProps$toolBarRen;
|
|
13
|
+
var shouldCollapse = options.shouldCollapse,
|
|
14
|
+
restProps = options.restProps;
|
|
15
|
+
var baseActions = ((_restProps$toolBarRen = restProps.toolBarRender) === null || _restProps$toolBarRen === void 0 ? void 0 : _restProps$toolBarRen.call(restProps)) || [];
|
|
16
|
+
if (!shouldCollapse || baseActions.length <= 1) {
|
|
17
|
+
return baseActions;
|
|
18
|
+
}
|
|
19
|
+
var _baseActions = _toArray(baseActions),
|
|
20
|
+
first = _baseActions[0],
|
|
21
|
+
rest = _baseActions.slice(1);
|
|
22
|
+
return [first, /*#__PURE__*/_jsx(Dropdown, {
|
|
23
|
+
menu: {
|
|
24
|
+
items: rest.map(function (item, index) {
|
|
25
|
+
return {
|
|
26
|
+
key: index,
|
|
27
|
+
label: item
|
|
28
|
+
};
|
|
29
|
+
})
|
|
30
|
+
},
|
|
31
|
+
trigger: ['click'],
|
|
32
|
+
children: /*#__PURE__*/_jsxs(Button, {
|
|
33
|
+
children: ["\u66F4\u591A ", /*#__PURE__*/_jsx(DownOutlined, {})]
|
|
34
|
+
})
|
|
35
|
+
}, "more")];
|
|
36
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@creekjs/web-components",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"father:build": "father build",
|
|
8
|
+
"father:dev": "father dev"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [],
|
|
11
|
+
"author": "",
|
|
12
|
+
"license": "ISC",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@ant-design/icons": "^5.5.1",
|
|
15
|
+
"@ant-design/pro-components": "^2.7.18",
|
|
16
|
+
"antd-style": "^3.7.1",
|
|
17
|
+
"zustand": "^5.0.1"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createStyles } from 'antd-style';
|
|
2
|
+
|
|
3
|
+
export type BgCenterProps = {
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const BgCenter = ({ children }: BgCenterProps) => {
|
|
8
|
+
const useStyles = createStyles(({ token }) => ({
|
|
9
|
+
bgCenterContianer: {
|
|
10
|
+
display: 'flex',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
justifyContent: 'center',
|
|
13
|
+
position: 'fixed',
|
|
14
|
+
top: 0,
|
|
15
|
+
left: 0,
|
|
16
|
+
right: 0,
|
|
17
|
+
bottom: 0,
|
|
18
|
+
backgroundColor: 'rgba(255, 255, 255, 0.7)',
|
|
19
|
+
zIndex: token.zIndexBase,
|
|
20
|
+
},
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
const { styles } = useStyles();
|
|
24
|
+
|
|
25
|
+
return <div className={styles.bgCenterContianer}>{children}</div>;
|
|
26
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CreekConfigContext, CreekConfigContextProps } from './CreekConfigContext';
|
|
2
|
+
|
|
3
|
+
export type CreekConfigProviderProps = CreekConfigContextProps & {
|
|
4
|
+
children?: React.ReactNode;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const CreekConfigProvider = (props: CreekConfigProviderProps) => {
|
|
8
|
+
const { children, ...more } = props;
|
|
9
|
+
return <CreekConfigContext.Provider value={more}>{children}</CreekConfigContext.Provider>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
CreekConfigProvider.CreekConfigContext = CreekConfigContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useViewportHeight';
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { useDebounceEffect, useDeepCompareEffect, useEventListener, useMemoizedFn, useMount, useUnmount } from 'ahooks';
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
interface UseViewportHeightOptions {
|
|
5
|
+
/** 底部保留空间(如固定在底部的元素高度),默认 0 */
|
|
6
|
+
bottomOffset?: number;
|
|
7
|
+
/** 顶部保留空间,默认自动计算到容器顶部的距离 */
|
|
8
|
+
topOffset?: number;
|
|
9
|
+
/** 额外的边距,默认 0 */
|
|
10
|
+
margin?: number;
|
|
11
|
+
/** 最小高度,默认 0 */
|
|
12
|
+
minHeight?: number;
|
|
13
|
+
/** 最大高度,不设置则无限制 */
|
|
14
|
+
maxHeight?: number;
|
|
15
|
+
/** 是否启用调试模式,会在控制台输出计算信息 */
|
|
16
|
+
debug?: boolean;
|
|
17
|
+
/** 防抖延迟时间(毫秒),默认 16ms */
|
|
18
|
+
debounceDelay?: number;
|
|
19
|
+
/** 依赖项数组,当这些值变化时会重新计算高度(比如搜索条件) */
|
|
20
|
+
deps?: React.DependencyList;
|
|
21
|
+
|
|
22
|
+
isObserverParent?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const useViewportHeight = (options: UseViewportHeightOptions = {}) => {
|
|
26
|
+
const { bottomOffset = 0, topOffset, margin = 0, minHeight = 0, maxHeight, debug = false, debounceDelay = 16, deps = [], isObserverParent } = options;
|
|
27
|
+
|
|
28
|
+
const [viewPortHeight, setHeight] = useState<number | undefined>(undefined);
|
|
29
|
+
let containerRef = useRef<HTMLDivElement| null>(null);
|
|
30
|
+
const resizeObserverRef = useRef<ResizeObserver | null>(null);
|
|
31
|
+
const mutationObserverRef = useRef<MutationObserver | null>(null);
|
|
32
|
+
|
|
33
|
+
// 使用 useMemoizedFn 缓存计算函数,避免不必要的重新创建
|
|
34
|
+
const calculateHeight = useMemoizedFn(() => {
|
|
35
|
+
if (!containerRef.current) return;
|
|
36
|
+
|
|
37
|
+
const container = containerRef.current;
|
|
38
|
+
const rect = container.getBoundingClientRect();
|
|
39
|
+
|
|
40
|
+
// 计算顶部偏移量
|
|
41
|
+
const calculatedTopOffset = topOffset ?? rect.top;
|
|
42
|
+
|
|
43
|
+
// 计算可用高度
|
|
44
|
+
const viewportHeight = window.innerHeight;
|
|
45
|
+
let availableHeight = viewportHeight - calculatedTopOffset - bottomOffset - margin;
|
|
46
|
+
|
|
47
|
+
// 应用最小/最大高度限制
|
|
48
|
+
if (minHeight > 0) {
|
|
49
|
+
availableHeight = Math.max(availableHeight, minHeight);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (maxHeight && maxHeight > 0) {
|
|
53
|
+
availableHeight = Math.min(availableHeight, maxHeight);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (debug) {
|
|
57
|
+
console.log('计算可视区域高度:', {
|
|
58
|
+
viewportHeight,
|
|
59
|
+
calculatedTopOffset,
|
|
60
|
+
bottomOffset,
|
|
61
|
+
margin,
|
|
62
|
+
minHeight,
|
|
63
|
+
maxHeight,
|
|
64
|
+
availableHeight,
|
|
65
|
+
containerRect: rect,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
setHeight(availableHeight);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// 使用 ahooks 的 useEventListener 监听窗口 resize 事件
|
|
73
|
+
useEventListener('resize', calculateHeight, { target: () => window });
|
|
74
|
+
|
|
75
|
+
// 使用 useDebounceEffect 处理依赖项变化时的防抖计算
|
|
76
|
+
useDebounceEffect(
|
|
77
|
+
() => {
|
|
78
|
+
if (containerRef.current) {
|
|
79
|
+
calculateHeight();
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
[...deps, topOffset, bottomOffset, margin, minHeight, maxHeight],
|
|
83
|
+
{ wait: debounceDelay },
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// 初始化计算
|
|
87
|
+
useMount(() => {
|
|
88
|
+
calculateHeight();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// 设置观察器
|
|
92
|
+
const setupObservers = useMemoizedFn(() => {
|
|
93
|
+
if (!containerRef.current) return;
|
|
94
|
+
|
|
95
|
+
const container = containerRef.current;
|
|
96
|
+
const observerParent = isObserverParent ? container.parentElement : container;
|
|
97
|
+
|
|
98
|
+
if(!observerParent) return;
|
|
99
|
+
|
|
100
|
+
cleanupObservers();
|
|
101
|
+
|
|
102
|
+
resizeObserverRef.current = new ResizeObserver(() => {
|
|
103
|
+
calculateHeight();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
resizeObserverRef.current.observe(container);
|
|
107
|
+
|
|
108
|
+
mutationObserverRef.current = new MutationObserver(() => {
|
|
109
|
+
setTimeout(calculateHeight, 0);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
mutationObserverRef.current.observe(observerParent, {
|
|
113
|
+
childList: true,
|
|
114
|
+
subtree: false, // 只监听直接子节点变化
|
|
115
|
+
attributes: false,
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// 清理观察器
|
|
120
|
+
const cleanupObservers = useMemoizedFn(() => {
|
|
121
|
+
if (resizeObserverRef.current) {
|
|
122
|
+
resizeObserverRef.current.disconnect();
|
|
123
|
+
resizeObserverRef.current = null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (mutationObserverRef.current) {
|
|
127
|
+
mutationObserverRef.current.disconnect();
|
|
128
|
+
mutationObserverRef.current = null;
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
// 组件卸载时清理
|
|
134
|
+
useUnmount(() => {
|
|
135
|
+
cleanupObservers();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
useDeepCompareEffect(() => {
|
|
139
|
+
if(containerRef.current) {
|
|
140
|
+
setupObservers();
|
|
141
|
+
}
|
|
142
|
+
}, [containerRef.current])
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
/** 容器引用,需要绑定到目标元素的容器 */
|
|
146
|
+
containerRef,
|
|
147
|
+
/** 计算得出的可视区域高度 */
|
|
148
|
+
viewPortHeight,
|
|
149
|
+
/** 手动重新计算高度的方法 */
|
|
150
|
+
recalculate: calculateHeight,
|
|
151
|
+
/** 是否已完成高度计算 */
|
|
152
|
+
isCalculated: viewPortHeight !== undefined,
|
|
153
|
+
};
|
|
154
|
+
};
|