Skip to content

Commit 1c65f8f

Browse files
authored
feat(VTimeline): side prop for individual items (#20855)
fixes #19363
1 parent bf13ecc commit 1c65f8f

File tree

4 files changed

+22
-7
lines changed

4 files changed

+22
-7
lines changed

packages/api-generator/src/locale/en/VTimeline.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"linePosition": "Shift the position of the line. By default the line will evenly split items before/after.",
99
"lineThickness": "Thickness of the timeline line.",
1010
"mirror": "Mirror the before/after ordering of timeline items.",
11-
"side": "Display all timeline items on one side of the timeline, either **before** or **after**.",
11+
"side": "Display all timeline items on one side of the timeline, either **start** or **end**.",
1212
"truncateLine": "Truncate timeline directly at the **start** or **end** of the line, or on **both** ends."
1313
}
1414
}

packages/api-generator/src/locale/en/VTimelineItem.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"iconColor": "Color of the icon.",
1111
"index": "Used to allow dynamically shown items to be re-inserted in the correct position.",
1212
"lineInset": "Specifies the distance between the line and the dot of the item.",
13-
"side": "Show the item either **before** or **after** the timeline. This will override the implicit ordering of items, but will in turn be overriden by the `v-timeline` **single-side** prop.",
13+
"side": "Display the item on one side of the timeline, either **start** or **end**. This will override the implicit ordering of items, unless `v-timeline` has it's own **side** prop defined.",
1414
"size": "Size of the item dot"
1515
},
1616
"slots": {

packages/vuetify/src/components/VTimeline/VTimeline.sass

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@
2323
grid-column-gap: $timeline-item-padding
2424
width: 100%
2525

26-
.v-timeline-item:nth-child(2n)
26+
.v-timeline--side-end > .v-timeline-item,
27+
&:not(.v-timeline--side-start) > .v-timeline-item--side-end,
28+
&:not(.v-timeline--side-start) > .v-timeline-item:nth-child(2n+1):not(.v-timeline-item--side-start)
2729
.v-timeline-item__body
2830
grid-row: 3
2931
padding-block-start: $timeline-item-padding
@@ -33,7 +35,9 @@
3335
padding-block-end: $timeline-item-padding
3436
align-self: flex-end
3537

36-
.v-timeline-item:nth-child(2n+1)
38+
.v-timeline--side-start > .v-timeline-item,
39+
&:not(.v-timeline--side-end) > .v-timeline-item--side-start,
40+
&:not(.v-timeline--side-end) > .v-timeline-item:nth-child(2n):not(.v-timeline-item--side-end)
3741
.v-timeline-item__body
3842
grid-row: 1
3943
padding-block-end: $timeline-item-padding
@@ -53,7 +57,9 @@
5357
@include timeline-last-item()
5458
padding-block-end: $timeline-item-padding
5559

56-
.v-timeline-item:nth-child(2n)
60+
.v-timeline--side-start > .v-timeline-item,
61+
&:not(.v-timeline--side-end) > .v-timeline-item--side-start,
62+
&:not(.v-timeline--side-end) > .v-timeline-item:nth-child(2n):not(.v-timeline-item--side-end)
5763
.v-timeline-item__body
5864
grid-column: 1
5965
padding-inline-end: $timeline-item-padding
@@ -62,7 +68,9 @@
6268
grid-column: 3
6369
padding-inline-start: $timeline-item-padding
6470

65-
.v-timeline-item:nth-child(2n+1)
71+
.v-timeline--side-end > .v-timeline-item,
72+
&:not(.v-timeline--side-start) > .v-timeline-item--side-end,
73+
&:not(.v-timeline--side-start) > .v-timeline-item:nth-child(2n+1):not(.v-timeline-item--side-start)
6674
.v-timeline-item__body
6775
grid-column: 3
6876
padding-inline-start: $timeline-item-padding

packages/vuetify/src/components/VTimeline/VTimelineItem.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ import { ref, shallowRef, watch } from 'vue'
1515
import { convertToUnit, genericComponent, propsFactory, useRender } from '@/util'
1616

1717
// Types
18-
import type { PropType } from 'vue'
18+
import type { Prop, PropType } from 'vue'
1919

2020
// Types
21+
export type TimelineItemSide = 'start' | 'end' | undefined
2122
export type VTimelineItemSlots = {
2223
default: never
2324
icon: never
@@ -36,6 +37,10 @@ export const makeVTimelineItemProps = propsFactory({
3637
icon: IconValue,
3738
iconColor: String,
3839
lineInset: [Number, String],
40+
side: {
41+
type: String,
42+
validator: (v: any) => v == null || ['start', 'end'].includes(v),
43+
} as Prop<TimelineItemSide>,
3944

4045
...makeComponentProps(),
4146
...makeDimensionProps(),
@@ -68,6 +73,8 @@ export const VTimelineItem = genericComponent<VTimelineItemSlots>()({
6873
'v-timeline-item',
6974
{
7075
'v-timeline-item--fill-dot': props.fillDot,
76+
'v-timeline-item--side-start': props.side === 'start',
77+
'v-timeline-item--side-end': props.side === 'end',
7178
},
7279
props.class,
7380
]}

0 commit comments

Comments
 (0)