UNPKG

react-admin-kit

Version:

A react based UI components for admin system

246 lines (221 loc) 7.82 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; Object.defineProperty(exports, "__esModule", { value: true }); exports.scanFormItems = exports.safeExecute = exports.normalizeSpan = exports.mergeEmptyItems = exports.extractSpanFromClassName = void 0; var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var _createForOfIteratorHelper2 = _interopRequireDefault(require("@babel/runtime/helpers/createForOfIteratorHelper")); /** * 表单项信息接口 */ /** * 响应式断点配置 */ /** * 从 CSS 类名中提取 span 值 * @param className CSS 类名字符串,如 'ant-col ant-col-8 ant-form-item' 或 'ant-col-xs-24 ant-col-md-8' * @returns 如果是传统 span 返回数字,如果是响应式断点返回 ResponsiveSpan 对象 */ var extractSpanFromClassName = exports.extractSpanFromClassName = function extractSpanFromClassName(className) { if (!className || typeof className !== 'string') { return 24; // 默认值 } // 匹配响应式断点模式: ant-col-{breakpoint}-{number} var responsiveMatches = className.match(/ant-col-(xs|sm|md|lg|xl|xxl)-(\d+)/g); if (responsiveMatches && responsiveMatches.length > 0) { var responsiveSpan = {}; responsiveMatches.forEach(function (match) { var breakpointMatch = match.match(/ant-col-(xs|sm|md|lg|xl|xxl)-(\d+)/); if (breakpointMatch && breakpointMatch[1] && breakpointMatch[2]) { var breakpoint = breakpointMatch[1]; var spanValue = parseInt(breakpointMatch[2], 10); // 验证 span 值的合理性(1-24) if (spanValue >= 1 && spanValue <= 24) { responsiveSpan[breakpoint] = spanValue; } } }); // 如果有有效的响应式断点,返回对象 if (Object.keys(responsiveSpan).length > 0) { return responsiveSpan; } } // 匹配传统 span 模式: ant-col-数字 var spanMatch = className.match(/ant-col-(\d+)/); if (spanMatch && spanMatch[1]) { var span = parseInt(spanMatch[1], 10); // 验证 span 值的合理性(1-24) if (span >= 1 && span <= 24) { return span; } } // 如果没有找到或值不合理,返回默认值 return 24; }; /** * 扫描表单容器中的表单项 * @returns 表单项信息数组 */ var scanFormItems = exports.scanFormItems = function scanFormItems(container, grid, embed) { return safeExecute(function () { var formItems = []; var selector; if (embed) { selector = grid ? '.form-item-wrapper > .ant-row > .ant-col' : '.form-item-wrapper > .ant-form-item'; } else { selector = grid ? 'form > .ant-row > .ant-col' : 'form > .ant-form-item'; } var antCols = container.querySelectorAll(selector); antCols.forEach(function (col) { var colElement = col; // 查找标签元素 var labelElement = colElement.querySelector('.ant-form-item-label'); var controlElement = colElement.querySelector('.ant-form-item-control'); // 如果没有 control 元素,跳过这个项 if (!controlElement) { return; } // 提取标签文本 var label = ''; if (labelElement) { label = labelElement.textContent || ''; // 移除可能的冒号和空格 label = label.replace(/[::]\s*$/, '').trim(); } // 提取内容 var content = controlElement.innerHTML || controlElement.textContent || ''; // 提取 span 值 var span = extractSpanFromClassName(colElement.className); // 检查是否为空项(没有标签且没有有意义的内容) // 移除 HTML 标签后检查是否为空 var textContent = controlElement.textContent || ''; var isEmpty = !label && !textContent.trim(); formItems.push({ label: label, content: content.trim(), span: span, element: colElement, isEmpty: isEmpty }); }); return formItems; }, [], 'Failed to scan form items'); }; // 处理空值合并:根据列数和 span 计算出行结构,如果有空项不在行开头的,就把空项的 span 合并进前一个项中 var mergeEmptyItems = exports.mergeEmptyItems = function mergeEmptyItems(items, column) { var mergedItems = []; var currentRowSpan = 0; var previousItem = null; var _iterator = (0, _createForOfIteratorHelper2.default)(items), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var item = _step.value; currentRowSpan += item.span; if (item.isEmpty && previousItem) { mergedItems[mergedItems.length - 1].span += item.span; } else { mergedItems.push(item); previousItem = item; } // 当当前行 span 总和达到或超过列数时,处理该行 if (currentRowSpan >= column) { // 重置行状态 currentRowSpan = 0; previousItem = null; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return mergedItems; }; /** * 规范化 Descriptions items 中的 span 值 * * 对于 Ant Design Descriptions 组件: * - 每行的 span 总和应该等于 column 值 * - 'filled' 会自动填充剩余空间 * - 当某个 item 的 span 会导致当前行总和超过 column 时,前一项应被设为 'filled' 来填满当前行 * * @param items - Descriptions 的 items 数组(span 只会是数字) * @param column - Descriptions 的 column 值(默认为 3) * @returns 规范化后的 items 数组 * * @example * ```ts * // 示例 1: 需要将某项设为 'filled' * normalizeSpan([{ span: 1 }, { span: 1 }, { span: 3 }], 3) * // => [{ span: 1 }, { span: 'filled' }, { span: 3 }] * * // 示例 2: 简单溢出 * normalizeSpan([{ span: 2 }, { span: 2 }], 3) * // => [{ span: 'filled' }, { span: 2 }] * ``` */ var normalizeSpan = exports.normalizeSpan = function normalizeSpan(items) { var column = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 3; if (!items || items.length === 0) { return []; } var normalizedItems = []; var currentRowSpan = 0; for (var i = 0; i < items.length; i++) { var item = items[i]; var span = item.span; var newTotal = currentRowSpan + span; // 当前项自己溢出 if (newTotal > column) { normalizedItems.push((0, _objectSpread2.default)((0, _objectSpread2.default)({}, item), {}, { span: 'filled' })); currentRowSpan = 0; continue; } // 刚好填满 if (newTotal === column) { normalizedItems.push(item); currentRowSpan = 0; continue; } // 未填满,检查下一项 var nextItem = items[i + 1]; // 没有下一项,保持当前项 if (!nextItem) { normalizedItems.push(item); currentRowSpan = newTotal; continue; } var nextSpan = nextItem.span; // 检查:当前项 + 下一项是否会溢出 if (newTotal + nextSpan > column) { // 会溢出,当前项填满当前行 normalizedItems.push((0, _objectSpread2.default)((0, _objectSpread2.default)({}, item), {}, { span: 'filled' })); currentRowSpan = 0; } else { // 不会溢出,保持当前项 normalizedItems.push(item); currentRowSpan = newTotal; } } return normalizedItems; }; /** * 安全执行函数,提供错误处理 */ /* istanbul ignore next */ var safeExecute = exports.safeExecute = function safeExecute(fn, fallback, errorMessage) { try { return fn(); } catch (error) { if (process.env.NODE_ENV === 'development') { console.warn("[SchemaForm Description Table] ".concat(errorMessage, ":"), error); } return fallback; } };