/
VTimeline.tsx
97 lines (83 loc) 路 2.55 KB
/
VTimeline.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Styles
import './VTimeline.sass'
// Components
import { VTimelineItem } from './VTimelineItem'
// Composables
import { makeTagProps } from '@/composables/tag'
import { makeDensityProps, useDensity } from '@/composables/density'
import { makeThemeProps, provideTheme } from '@/composables/theme'
// Helpers
import { computed, provide, toRef } from 'vue'
import { convertToUnit, defineComponent } from '@/util'
import { VTimelineSymbol } from './shared'
// Types
import type { Prop } from 'vue'
export type TimelineDirection = 'vertical' | 'horizontal'
export type TimelineSide = 'before' | 'after' | undefined
export const VTimeline = defineComponent({
name: 'VTimeline',
props: {
direction: {
type: String,
default: 'vertical',
validator: (v: any) => ['vertical', 'horizontal'].includes(v),
} as Prop<TimelineDirection>,
side: {
type: String,
validator: (v: any) => v == null || ['start', 'end'].includes(v),
} as Prop<TimelineSide>,
lineInset: {
type: [String, Number],
default: 0,
},
lineThickness: {
type: [String, Number],
default: 2,
},
lineColor: String,
truncateLine: {
type: String,
default: 'start',
validator: (v: any) => ['none', 'start', 'end', 'both'].includes(v),
},
...makeDensityProps(),
...makeTagProps(),
...makeThemeProps(),
},
setup (props, { slots }) {
const { themeClasses } = provideTheme(props)
const { densityClasses } = useDensity(props)
provide(VTimelineSymbol, {
density: toRef(props, 'density'),
lineColor: toRef(props, 'lineColor'),
})
const sideClass = computed(() => {
const side = props.side ? props.side : props.density !== 'default' ? 'end' : null
return side && `v-timeline--side-${side}`
})
return () => (
<props.tag
class={[
'v-timeline',
`v-timeline--${props.direction}`,
{
'v-timeline--inset-line': !!props.lineInset,
'v-timeline--truncate-line-end': props.truncateLine === 'end' || props.truncateLine === 'both',
},
themeClasses.value,
densityClasses.value,
sideClass.value,
]}
style={{
'--v-timeline-line-thickness': convertToUnit(props.lineThickness),
'--v-timeline-line-inset': convertToUnit(props.lineInset),
}}
>
{ (props.truncateLine === 'none' || props.truncateLine === 'end') && (
<VTimelineItem hideDot />
) }
{ slots.default?.() }
</props.tag>
)
},
})