@fesjs/fes-design
Version:
fes-design for PC
100 lines (95 loc) • 3.93 kB
JavaScript
import { ref, inject, watch, onUnmounted, reactive, provide, computed } from 'vue';
import useResize from '../_util/use/useResize';
import { ICON_DEFAULT_SIDE_LENGTH, ICON_PADDING, COMPONENT_NAME } from './const';
import { calcDimensionProp, calcInlineStartProp, calcLengthProp } from './utils';
const CUSTOM_ICONS_PROVIDE_KEY = Symbol(`${COMPONENT_NAME}CustomIconsProvideKey`);
const useCustomIconRegister = (nodeIndex, isIconCustom) => {
const iconRef = ref(null);
const {
registerIcon,
updateIcon,
removeRegistration
} = inject(CUSTOM_ICONS_PROVIDE_KEY);
useResize(iconRef, entries => {
if (!isIconCustom.value) {
return;
}
const iconRect = entries[0].contentRect;
updateIcon(nodeIndex, iconRect);
});
watch(isIconCustom, isCustom => {
if (!isCustom) {
removeRegistration(nodeIndex);
return;
}
registerIcon(nodeIndex);
});
onUnmounted(() => removeRegistration(nodeIndex));
return {
iconRef
};
};
// 保证在存在自定义的轴点图标时,轴线的长度能满足与图标有 padding
const useCustomIcons = (axisDirection, nodes) => {
const customIconRectMap = reactive(new Map());
const registerIcon = nodeIndex => {
customIconRectMap.set(nodeIndex, undefined);
};
const updateIcon = (nodeIndex, iconRect) => {
customIconRectMap.set(nodeIndex, iconRect);
};
const removeRegistration = nodeIndex => {
customIconRectMap.delete(nodeIndex);
};
provide(CUSTOM_ICONS_PROVIDE_KEY, {
registerIcon,
updateIcon,
removeRegistration
});
// 当前 node 或下一 node 的轴点图标为自定义时,当前 node 就需要调整样式
const nodeNeedAdjustIndexes = computed(() => {
const customIconIndexes = Array.from(customIconRectMap.keys());
return nodes.reduce((result, _, currentIndex) => {
if (customIconIndexes.includes(currentIndex)) {
return [...result, currentIndex];
}
if (customIconIndexes.includes(currentIndex + 1)) {
return [...result, currentIndex];
}
return result;
}, []);
});
const nodeAppendantStyleMap = computed(() => {
const styleMap = new Map();
nodeNeedAdjustIndexes.value.forEach(nodeIndex => {
var _currentIconRect$dime, _nextIconRect$dimensi;
const currentIconRect = customIconRectMap.get(nodeIndex);
const nextIconRect = customIconRectMap.get(nodeIndex + 1);
const dimension = calcDimensionProp(axisDirection);
const inlineStartProp = calcInlineStartProp(axisDirection);
const lengthProp = calcLengthProp(axisDirection);
const currentIconLength = (_currentIconRect$dime = currentIconRect === null || currentIconRect === void 0 ? void 0 : currentIconRect[dimension]) !== null && _currentIconRect$dime !== void 0 ? _currentIconRect$dime : ICON_DEFAULT_SIDE_LENGTH;
const nextIconLength = (_nextIconRect$dimensi = nextIconRect === null || nextIconRect === void 0 ? void 0 : nextIconRect[dimension]) !== null && _nextIconRect$dimensi !== void 0 ? _nextIconRect$dimensi : ICON_DEFAULT_SIDE_LENGTH;
let contentStyle = {};
if (axisDirection !== 'column' && currentIconRect) {
// 纵向内容不需要根据轴点图标的边长调整位置,只根据默认行高进行偏移
// 当前 node 不存在 customIcon 时,也不需要对 node 的标题、辅助说明进行额外的偏移
contentStyle = {
[inlineStartProp]: `calc(0px - ${currentIconLength}px / 2)`
};
}
styleMap.set(nodeIndex, {
content: contentStyle,
tail: {
[inlineStartProp]: `calc(${currentIconLength}px / 2 + ${ICON_PADDING}px)`,
[lengthProp]: `calc(100% - ${currentIconLength}px / 2 - ${nextIconLength}px / 2 - ${ICON_PADDING}px * 2)`
}
});
});
return styleMap;
});
return {
nodeAppendantStyleMap
};
};
export { useCustomIconRegister, useCustomIcons };