UNPKG

@fesjs/fes-design

Version:
157 lines (151 loc) 4.72 kB
import { defineComponent, computed, createVNode, Fragment } from 'vue'; import { useTheme } from '../_theme/useTheme'; import { timelineProps } from './props'; import { COMPONENT_NAME, prefixCls } from './const'; import { cls, calcTitlePosition, calcDescPosition, getTitleOppositePosition } from './utils'; import { useCustomIcons } from './useCustomIcons'; import Icon from './icon'; /** 渲染标题、辅助描述 */ const renderNodeContent = _ref => { let { title, titlePosition, descPosition, desc, titleClass, descClass, appendantStyle, titleWidth, direction } = _ref; const titleElement = createVNode("div", { "class": [cls('item-title'), cls(`item-title-layout-${titlePosition}`), titleClass] }, [title]); const descElement = desc ? createVNode("div", { "class": [cls('item-desc'), cls(`item-desc-layout-${descPosition}`), descClass] }, [desc]) : undefined; // 标题、辅助描述同侧 if (descPosition !== 'opposite') { return createVNode("div", { "class": [cls('item-content-wrapper'), cls(`item-content-wrapper-${titlePosition}`)], "style": appendantStyle }, [titleElement, descElement]); } // 标题、辅助描述分侧 return createVNode(Fragment, null, [createVNode("div", { "class": [cls('item-content-wrapper'), cls(`item-content-wrapper-${titlePosition}`)], "style": [appendantStyle, direction === 'column' && descPosition === 'opposite' && titleWidth && { width: titleWidth }] }, [titleElement]), descElement && createVNode("div", { "class": [cls('item-content-wrapper'), cls(`item-content-wrapper-${getTitleOppositePosition(titlePosition)}`)], "style": appendantStyle }, [descElement])]); }; const renderNode = nodeProps => { const { node, index, props, slots, nodeAppendantStyleMap } = nodeProps; const { direction, titlePosition, descPosition, titleClass, descClass } = props; const { title, desc, icon } = node; const calculatedTitlePosition = calcTitlePosition(index, titlePosition, node.titlePosition); const calculatedDescPosition = calcDescPosition(direction, descPosition); let descContent; // prop 的渲染函数优先级高于插槽 if (slots.desc) { descContent = slots.desc({ index, item: props.data[index] }); } else if (typeof desc === 'function') { descContent = desc({ index, item: props.data[index] }); } else { descContent = desc; } // prop 的渲染函数优先级高于插槽 let titleContent; if (slots.title) { titleContent = slots.title({ index, item: props.data[index] }); } else if (typeof title === 'function') { titleContent = title({ index, item: props.data[index] }); } else { titleContent = title; } const appendantStyle = nodeAppendantStyleMap.value.get(index); return createVNode("li", { "class": [cls('item'), cls(`item-layout-${calculatedTitlePosition}`)], "key": index }, [createVNode("div", { "class": [cls('item-tail'), index === props.data.length - 1 && cls('item-tail-last')], "style": [appendantStyle === null || appendantStyle === void 0 ? void 0 : appendantStyle.tail, props.direction === 'column' && descPosition === 'opposite' && props.titleWidth && { left: props.titleWidth }] }, null), renderNodeContent({ title: titleContent, titleClass, descClass, titlePosition: calculatedTitlePosition, descPosition: calculatedDescPosition, desc: descContent, appendantStyle: appendantStyle === null || appendantStyle === void 0 ? void 0 : appendantStyle.content, titleWidth: props.titleWidth, direction: props.direction }), createVNode(Icon, { "key": index, "index": index, "icon": icon, "data": props.data, "style": [props.direction === 'column' && descPosition === 'opposite' && props.titleWidth && { left: props.titleWidth }], "slotRender": slots.icon }, null)]); }; var timeline = defineComponent({ name: COMPONENT_NAME, props: timelineProps, slots: Object, setup: (props, _ref2) => { let { slots } = _ref2; useTheme(); const { nodeAppendantStyleMap } = useCustomIcons(props.direction, props.data); const classList = computed(() => [prefixCls, cls(`direction-${props.direction}`), cls(`layout-${props.titlePosition}`), cls(`desc-${props.descPosition}`)]); return () => createVNode("ul", { "class": classList.value }, [props.data.map((node, index) => renderNode({ node, index, props, slots, nodeAppendantStyleMap }))]); } }); export { timeline as default };