Skip to content

Commit

Permalink
feat: timeline支持title插槽和设置labelWidth
Browse files Browse the repository at this point in the history
  • Loading branch information
wanchun committed Aug 28, 2024
1 parent ebff401 commit 675870f
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 18 deletions.
7 changes: 6 additions & 1 deletion components/timeline/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export interface TimelineNodeSlotCommonParams {

/** 时间轴结点的参数 */
export interface TimelineNode {
title: string;
title: string | ((params: TimelineNodeSlotCommonParams) => VNodeChild);
titlePosition?: StrictExtract<TimelineTitlePosition, 'start' | 'end'>;
desc?: string | ((params: TimelineNodeSlotCommonParams) => VNodeChild);
icon?:
Expand Down Expand Up @@ -87,6 +87,10 @@ export const timelineProps = {
},
titleClass: { type: String },
descClass: { type: String },
titleWidth: {
type: String,
default: '50%',
},
} as const satisfies ComponentObjectPropsOptions;

// 组件暴露给外部的 props 类型
Expand All @@ -98,6 +102,7 @@ export type TimelineInnerProps = ComponentInnerProps<typeof timelineProps>;
export type TimelineSlotsParams = {
desc: TimelineNodeSlotCommonParams;
icon: TimelineNodeSlotCommonParams;
title: TimelineNodeSlotCommonParams;
};

export type TimelineSlots = SlotsType<TimelineSlotsParams>;
Expand Down
56 changes: 45 additions & 11 deletions components/timeline/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ ul.@{timeline}.@{timeline}-direction-column {
left: 0;
transform: translate(-50%, -50%);
}

.@{item}-tail {
left: 0;
transform: translateX(-50%);
}

.@{item}-content-wrapper {
top: calc(0px - @item-line-height / 2);
margin-left: calc(@icon-side-length / 2 + @item-axis-space);
Expand Down Expand Up @@ -200,9 +200,7 @@ ul.@{timeline}.@{timeline}-direction-column {
}

// 时间轴垂直方向,且轴在中间
&.@{timeline}-layout-alternate,
// 时间轴垂直方向,辅助信息与标题分侧
&.@{timeline}-desc-opposite {
&.@{timeline}-layout-alternate {
li.@{item} {
display: grid;
grid-template-areas: 'start end';
Expand All @@ -229,7 +227,7 @@ ul.@{timeline}.@{timeline}-direction-column {
padding-right: calc(@icon-side-length / 2 + @item-axis-space);
text-align: right;
}


// 轴右侧结点
.@{item}-content-wrapper-end {
Expand All @@ -239,10 +237,46 @@ ul.@{timeline}.@{timeline}-direction-column {
}
}
}

// 时间轴垂直方向,辅助信息与标题分侧
&.@{timeline}-desc-opposite {
li.@{item} {
display: flex;

.@{item}-icon {
top: 0;
left: 50%;
transform: translate(-50%, -50%);
}

.@{item}-tail {
left: 50%;
transform: translateX(-50%);
}

.@{item}-content-wrapper {
top: calc(0px - @item-line-height / 2);
}

// 轴左侧结点
.@{item}-content-wrapper-start {
padding-right: calc(@icon-side-length / 2 + @item-axis-space);
text-align: right;
}


// 轴右侧结点
.@{item}-content-wrapper-end {
flex: 1;
padding-left: calc(@icon-side-length / 2 + @item-axis-space);
text-align: left;
}
}
}
}

// 时间轴水平方向
ul.@{timeline}.@{timeline}-direction-row,
ul.@{timeline}.@{timeline}-direction-row,
ul.@{timeline}.@{timeline}-direction-row-reverse {
li.@{item} {
flex-grow: 1;
Expand Down Expand Up @@ -291,7 +325,7 @@ ul.@{timeline}.@{timeline}-direction-row-reverse {
grid-template-rows: 1fr 1fr;

.@{item}-content-wrapper {
display: flex;
display: flex;
flex-direction: column;

// 轴上方结点
Expand Down Expand Up @@ -341,7 +375,7 @@ ul.@{timeline}.@{timeline}-direction-row {
left: 0;
transform: translate(-50%, -50%);
}

.@{item}-content-wrapper {
margin-top: calc(@icon-side-length / 2 + @item-axis-space);
}
Expand Down Expand Up @@ -402,7 +436,7 @@ ul.@{timeline}.@{timeline}-direction-row-reverse {
right: 0;
transform: translate(50%, -50%);
}

.@{item}-content-wrapper {
margin-top: calc(@icon-side-length / 2 + @item-axis-space);
}
Expand Down Expand Up @@ -436,4 +470,4 @@ ul.@{timeline}.@{timeline}-direction-row-reverse {
}
}
}
}
}
26 changes: 21 additions & 5 deletions components/timeline/timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ const renderNodeContent = ({
titleClass,
descClass,
appendantStyle,
}: Pick<TimelineNode, 'title' | 'titlePosition'> &
Pick<Props, 'descPosition' | 'titleClass' | 'descClass'> & {
titleWidth,
direction,
}: Pick<TimelineNode, 'titlePosition'> &
Pick<Props, 'descPosition' | 'titleClass' | 'descClass' | 'titleWidth' | 'direction'> & {
title: VNodeChild;
desc?: VNodeChild;
appendantStyle?: CSSProperties;
}): VNode => {
Expand Down Expand Up @@ -86,7 +89,7 @@ Pick<Props, 'descPosition' | 'titleClass' | 'descClass'> & {
cls('item-content-wrapper'),
cls(`item-content-wrapper-${titlePosition}`),
]}
style={appendantStyle}
style={[appendantStyle, direction === 'column' && descPosition === 'opposite' && titleWidth && { width: titleWidth }]}
>
{titleElement}
</div>
Expand Down Expand Up @@ -140,6 +143,16 @@ const renderNode = (nodeProps: {
descContent = desc;
}

// prop 的渲染函数优先级高于插槽
let titleContent: VNodeChild;
if (slots.title) {
titleContent = slots.title({ index });
} else if (typeof title === 'function') {
titleContent = title({ index });
} else {
titleContent = title;
}

const appendantStyle = nodeAppendantStyleMap.value.get(index);

return (
Expand All @@ -152,21 +165,24 @@ const renderNode = (nodeProps: {
cls('item-tail'),
index === props.data.length - 1 && cls('item-tail-last'),
]}
style={appendantStyle?.tail}
style={[appendantStyle?.tail, props.direction === 'column' && descPosition === 'opposite' && props.titleWidth && { left: props.titleWidth }]}
/>
{renderNodeContent({
title,
title: titleContent,
titleClass,
descClass,
titlePosition: calculatedTitlePosition,
descPosition: calculatedDescPosition,
desc: descContent,
appendantStyle: appendantStyle?.content,
titleWidth: props.titleWidth,
direction: props.direction,
})}
<Icon
key={index}
index={index}
icon={icon}
style={[props.direction === 'column' && descPosition === 'opposite' && props.titleWidth && { left: props.titleWidth }]}
slotRender={slots.icon}
/>
</li>
Expand Down
12 changes: 12 additions & 0 deletions docs/.vitepress/components/timeline/customDesc.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@
自定义辅助描述
</span>
</template>
<template #title="{ index }">
<span
:style="{
color:
index === data2.length - 1
? '#ff007f'
: 'var(--f-primary-color)',
}"
>
自定义标题
</span>
</template>
</FTimeline>
<FDivider />
<FTimeline :data="data1">
Expand Down
8 changes: 7 additions & 1 deletion docs/.vitepress/components/timeline/descPosition.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@
:descPosition="descPosition ?? undefined"
titlePosition="start"
class="timeline"
/>
>
<template #title="{ index }">
<span style="width: 200px;">
自定义标题 {{ index }}
</span>
</template>
</FTimeline>
</template>

<script setup lang="ts">
Expand Down

0 comments on commit 675870f

Please sign in to comment.