react-admin-kit
Version:
A react based UI components for admin system
152 lines (140 loc) • 5.45 kB
JavaScript
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { Descriptions, Grid } from 'antd';
import { scanFormItems, mergeEmptyItems, normalizeSpan } from "./utils/descriptions-table";
import { jsx as _jsx } from "react/jsx-runtime";
var useBreakpoint = Grid.useBreakpoint;
var DescriptionsTable = function DescriptionsTable(_ref) {
var formContainerRef = _ref.formContainerRef,
grid = _ref.grid,
embed = _ref.embed,
layout = _ref.layout,
_ref$descriptionsProp = _ref.descriptionsProps,
descriptionsProps = _ref$descriptionsProp === void 0 ? {} : _ref$descriptionsProp;
var screens = useBreakpoint();
var _useState = useState([]),
_useState2 = _slicedToArray(_useState, 2),
formItems = _useState2[0],
setFormItems = _useState2[1];
var scanAndUpdateFormItems = useCallback(function () {
if (!formContainerRef.current) {
setFormItems([]);
return;
}
var scannedItems = scanFormItems(formContainerRef.current, grid, embed);
setFormItems(scannedItems);
}, [formContainerRef]);
useEffect(function () {
// 初始扫描
scanAndUpdateFormItems();
// 设置 MutationObserver 监听 DOM 变化
if (!formContainerRef.current) {
return;
}
/* istanbul ignore next */
var observer = new MutationObserver(function (mutations) {
// 检查是否有相关的 DOM 变化
var shouldUpdate = mutations.some(function (mutation) {
// 监听元素增删、属性变化(特别是 class 变化会影响 span 值)
return mutation.type === 'childList' || mutation.type === 'attributes' && mutation.attributeName === 'class';
});
if (shouldUpdate) {
scanAndUpdateFormItems();
}
});
// 开始监听
observer.observe(formContainerRef.current, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['class']
});
// 清理函数
return function () {
observer.disconnect();
};
}, [formContainerRef, scanAndUpdateFormItems]);
var _useMemo = useMemo(function () {
// 获取当前有效的断点,按优先级排序
var activeBreakpoints = Object.entries(screens).filter(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
_ = _ref3[0],
isActive = _ref3[1];
return isActive;
}).map(function (_ref4) {
var _ref5 = _slicedToArray(_ref4, 1),
breakpoint = _ref5[0];
return breakpoint;
}).sort(function (a, b) {
var breakpointOrder = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
return breakpointOrder.indexOf(a) - breakpointOrder.indexOf(b);
});
// 计算每个表单项在当前屏幕下的实际 span 值
var resolvedSpans = formItems.map(function (item) {
var span = item.span;
// 如果是数字,直接使用
if (typeof span === 'number') {
return span;
}
// 如果是响应式对象,按断点优先级查找合适的值
var responsiveSpan = span;
// 按优先级查找第一个有效的断点值
var _iterator = _createForOfIteratorHelper(activeBreakpoints),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var breakpoint = _step.value;
if (responsiveSpan[breakpoint] !== undefined) {
return responsiveSpan[breakpoint];
}
}
// 如果没有找到响应式值,返回默认值 24
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return 24;
});
// 找到最小的 span 值
var minSpan = resolvedSpans.length > 0 ? Math.min.apply(Math, _toConsumableArray(resolvedSpans)) : 24;
// 计算列数:24 / 最小 span,向上取整
var calculatedColumn = minSpan > 0 ? Math.ceil(24 / minSpan) : 1;
// 计算每个表单项在 Descriptions 中的 span 值
var descriptionItems = formItems.map(function (item, index) {
var currentSpan = resolvedSpans[index];
var descriptionsSpan = Math.ceil(currentSpan / minSpan);
return {
label: item.label,
children: /*#__PURE__*/_jsx("div", {
dangerouslySetInnerHTML: {
__html: item.content
}
}),
span: Math.max(1, descriptionsSpan),
isEmpty: item.isEmpty
};
});
var handledEmptyItems = mergeEmptyItems(descriptionItems, calculatedColumn);
var normalizedSpanItems = normalizeSpan(handledEmptyItems, calculatedColumn);
return {
descriptionItems: normalizedSpanItems,
column: calculatedColumn
};
}, [formItems, screens]),
descriptionItems = _useMemo.descriptionItems,
column = _useMemo.column;
if (descriptionItems.length === 0) {
return null;
}
return /*#__PURE__*/_jsx(Descriptions, _objectSpread(_objectSpread({
layout: layout
}, descriptionsProps), {}, {
column: column,
items: descriptionItems
}));
};
export default DescriptionsTable;