1
1
import './Timeline.css' ;
2
2
import { Key , useEffect , useRef } from 'react' ;
3
3
import { PropsWithKey , TimelineItem , TimelineItemProps } from './TimelineItem' ;
4
-
5
- type OffsetConfig = number | { left ?: number ; right ?: number } ;
6
-
7
- const resolveOffsets = ( offset : OffsetConfig ) =>
8
- typeof offset === 'number' ? { right : offset , left : 0 } : { right : offset . right ?? 0 , left : offset . left ?? 0 } ;
9
-
10
- const MIN_MARKER_OFFSET = 50 ;
11
-
12
- const getMarkerCompensationOffset = ( left : number , right : number ) => {
13
- const heightDifference = Math . abs ( left - right ) ;
14
- if ( heightDifference < MIN_MARKER_OFFSET ) {
15
- return MIN_MARKER_OFFSET - heightDifference ;
16
- }
17
- return 0 ;
18
- } ;
4
+ import { OffsetConfig , resolveOffsets } from '../models/offset' ;
19
5
20
6
export type TimelineProps = {
21
7
items : PropsWithKey < TimelineItemProps > [ ] ;
22
8
gap ?: number ;
23
9
offset ?: OffsetConfig ;
10
+ minMarkerGap ?: number ;
24
11
dateFormat ?: string ;
25
12
dateLocale ?: Locale ;
26
13
className ?: string ;
@@ -29,11 +16,12 @@ export type TimelineProps = {
29
16
const defaultTimelineConfig : Partial < TimelineProps > = {
30
17
gap : 50 ,
31
18
offset : 50 ,
19
+ minMarkerGap : 50 ,
32
20
dateFormat : 'P' ,
33
21
} ;
34
22
35
23
export function Timeline ( props : TimelineProps ) {
36
- const { items, gap, offset, className, dateFormat, dateLocale } = { ...defaultTimelineConfig , ...props } ;
24
+ const { items, gap, offset, minMarkerGap , className, dateFormat, dateLocale } = { ...defaultTimelineConfig , ...props } ;
37
25
38
26
const timelineRef = useRef < HTMLDivElement > ( null ) ;
39
27
const itemsRef = useRef < Map < Key , HTMLElement > > ( ) ;
@@ -46,6 +34,16 @@ export function Timeline(props: TimelineProps) {
46
34
return itemsRef . current ;
47
35
}
48
36
37
+ function getMinMarkerGapCompensation ( left : number , right : number ) {
38
+ if ( minMarkerGap ) {
39
+ const heightDifference = Math . abs ( left - right ) ;
40
+ if ( heightDifference < minMarkerGap ) {
41
+ return minMarkerGap - heightDifference ;
42
+ }
43
+ }
44
+ return 0 ;
45
+ }
46
+
49
47
function positionTimelineItems ( ) {
50
48
const elements = Array . from ( getRefMap ( ) . values ( ) ) ;
51
49
@@ -57,14 +55,14 @@ export function Timeline(props: TimelineProps) {
57
55
const element = item ;
58
56
59
57
if ( leftHeight > rightHeight ) {
60
- leftHeight += getMarkerCompensationOffset ( leftHeight , rightHeight ) ;
58
+ leftHeight += getMinMarkerGapCompensation ( leftHeight , rightHeight ) ;
61
59
62
60
element . style . top = `${ rightHeight } px` ;
63
61
element . classList . add ( 'timeline-item--right' ) ;
64
62
element . classList . remove ( 'timeline-item--left' ) ;
65
63
rightHeight += element . offsetHeight + ( gap ?? 0 ) ;
66
64
} else {
67
- rightHeight += getMarkerCompensationOffset ( leftHeight , rightHeight ) ;
65
+ rightHeight += getMinMarkerGapCompensation ( leftHeight , rightHeight ) ;
68
66
69
67
element . style . top = `${ leftHeight } px` ;
70
68
element . classList . add ( 'timeline-item--left' ) ;
0 commit comments