@ant-design/x
Version:
Craft AI-driven interfaces effortlessly
137 lines (128 loc) • 3.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = require("react");
// 支持的输入类型集合
const SUPPORTED_INPUT_TYPES = new Set(['input', 'select', 'custom', 'content']);
/**
* 从 slot 配置中提取默认值构建 slotValues
*/
const buildSlotValues = slotConfig => slotConfig?.reduce((acc, node) => {
const {
key,
type
} = node;
if (!key) return acc;
const props = node.props || {};
const defaultValue = SUPPORTED_INPUT_TYPES.has(type) ? props.defaultValue : props.value ?? props.label;
acc[key] = defaultValue ?? '';
return acc;
}, {}) ?? {};
/**
* 将 slot 配置数组转换为 Map 结构便于查找
*/
const buildSlotConfigMap = (slotConfig, slotConfigMap) => {
slotConfig?.forEach(node => {
if (node.key) slotConfigMap.set(node.key, node);
});
};
/**
* 根据目标节点和配置映射获取节点信息
*/
const getNodeInfoBySlotConfigMap = (targetNode, slotConfigMap) => {
if (!targetNode?.dataset) return null;
const {
dataset
} = targetNode;
return {
slotKey: dataset.slotKey,
placeholder: dataset.placeholder,
nodeType: dataset.nodeType,
skillKey: dataset.skillKey,
slotConfig: dataset.slotKey ? slotConfigMap.get(dataset.slotKey) : undefined,
targetNode
};
};
const useSlotConfigState = slotConfig => {
const [state, _setState] = (0, _react.useState)({});
const stateRef = (0, _react.useRef)(state);
const slotConfigMapRef = (0, _react.useRef)(new Map());
// 初始化 slotConfig
(0, _react.useEffect)(() => {
if (!slotConfig) return;
slotConfigMapRef.current.clear();
buildSlotConfigMap(slotConfig, slotConfigMapRef.current);
const newValues = buildSlotValues(slotConfig);
_setState(newValues);
stateRef.current = newValues;
}, [slotConfig]);
const setState = (0, _react.useCallback)(newValue => {
const value = typeof newValue === 'function' ? newValue(stateRef.current) : newValue;
_setState(value);
stateRef.current = value;
}, []);
const mergeSlotConfig = (0, _react.useCallback)(newSlotConfig => {
const newValues = buildSlotValues(newSlotConfig);
// 更新配置映射
newSlotConfig.forEach(node => {
if (node.key) slotConfigMapRef.current.set(node.key, node);
});
_setState(prev => ({
...prev,
...newValues
}));
stateRef.current = {
...stateRef.current,
...newValues
};
}, []);
const getNodeInfo = (0, _react.useCallback)(targetNode => getNodeInfoBySlotConfigMap(targetNode, slotConfigMapRef.current), []);
const getNodeTextValue = node => {
const nodeType = node.nodeType;
if (nodeType === Node.TEXT_NODE) {
return node.textContent || '';
}
if (nodeType !== Node.ELEMENT_NODE) {
return '';
}
const element = node;
const nodeInfo = getNodeInfo(element);
// 无节点信息,直接返回文本内容
if (!nodeInfo) {
return element.innerText || '';
}
const {
slotKey,
skillKey,
nodeType: infoNodeType,
slotConfig
} = nodeInfo;
if (skillKey) {
return '';
}
// 缓存文本内容,避免重复获取
const textContent = element.innerText || '';
// 处理 slot 节点
if (slotKey) {
if (infoNodeType === 'nbsp') {
return ' ';
}
if (!slotConfig || slotConfig.type === 'content') {
return textContent;
}
const slotValue = stateRef.current[slotKey] ?? '';
return slotConfig.formatResult?.(slotValue) ?? slotValue;
}
return textContent;
};
return [slotConfigMapRef.current, {
getSlotValues: () => stateRef.current,
setSlotValues: setState,
mergeSlotConfig,
getNodeInfo,
getNodeTextValue
}];
};
var _default = exports.default = useSlotConfigState;