Skip to content

Commit d64c857

Browse files
committed
feat: date formatting
1 parent 9c8773d commit d64c857

File tree

4 files changed

+48
-17
lines changed

4 files changed

+48
-17
lines changed

package-lock.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"@vitejs/plugin-react": "^3.0.0",
7676
"babel-loader": "^9.1.0",
7777
"conventional-github-releaser": "3.1.5",
78+
"date-fns": "^2.29.3",
7879
"eslint": "^8.30.0",
7980
"eslint-config-airbnb": "19.0.4",
8081
"eslint-config-airbnb-typescript": "^17.0.0",

src/components/Timeline.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import './Timeline.css';
2-
import { useEffect, useRef } from 'react';
2+
import { Key, useEffect, useRef } from 'react';
33
import { PropsWithKey, TimelineItem, TimelineItemProps } from './TimelineItem';
44

55
type OffsetConfig = number | { left?: number; right?: number };
@@ -21,19 +21,22 @@ export type TimelineProps = {
2121
items: PropsWithKey<TimelineItemProps>[];
2222
gap?: number;
2323
offset?: OffsetConfig;
24+
dateFormat?: string;
25+
dateLocale?: Locale;
2426
className?: string;
2527
};
2628

2729
const defaultTimelineConfig: Partial<TimelineProps> = {
2830
gap: 50,
2931
offset: 50,
32+
dateFormat: 'P',
3033
};
3134

3235
export function Timeline(props: TimelineProps) {
33-
const { items, gap, offset, className } = { ...defaultTimelineConfig, ...props };
36+
const { items, gap, offset, className, dateFormat, dateLocale } = { ...defaultTimelineConfig, ...props };
3437

3538
const timelineRef = useRef<HTMLDivElement>(null);
36-
const itemsRef = useRef<Map<Date, HTMLElement>>();
39+
const itemsRef = useRef<Map<Key, HTMLElement>>();
3740

3841
function getRefMap() {
3942
if (!itemsRef.current) {
@@ -87,13 +90,15 @@ export function Timeline(props: TimelineProps) {
8790
<div className="timeline__line" />
8891
{items.map((item) => (
8992
<TimelineItem
93+
dateFormat={dateFormat}
94+
dateLocale={dateLocale}
9095
{...item}
9196
ref={(node) => {
9297
const map = getRefMap();
9398
if (node) {
94-
map.set(item.date, node);
99+
map.set(item.key, node);
95100
} else {
96-
map.delete(item.date);
101+
map.delete(item.key);
97102
}
98103
}}
99104
/>

src/components/TimelineItem.tsx

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
import { forwardRef, Key, PropsWithChildren } from 'react';
2+
import { format } from 'date-fns';
23

34
export type PropsWithKey<T> = T & {
45
key: Key;
56
};
67

78
export type TimelineItemProps = PropsWithChildren<{
89
className?: string;
9-
date: Date;
10+
date: Date | string;
11+
dateFormat?: string;
12+
dateLocale?: Locale;
1013
title: string;
1114
}>;
1215

13-
export const TimelineItem = forwardRef<HTMLDivElement, TimelineItemProps>(({ className, title, date, children }, ref) => {
14-
return (
15-
<div ref={ref} className={['timeline-item', className].join(' ')}>
16-
<div className="timeline-item__marker" />
17-
<div className="timeline-card">
18-
<p className="timeline-card__date">{date.toISOString()}</p>
19-
<p className="timeline-card__title">{title}</p>
20-
{children}
16+
export const TimelineItem = forwardRef<HTMLDivElement, TimelineItemProps>(
17+
({ className, title, date, children, dateFormat, dateLocale }, ref) => {
18+
return (
19+
<div ref={ref} className={['timeline-item', className].join(' ')}>
20+
<div className="timeline-item__marker" />
21+
<div className="timeline-card">
22+
<p className="timeline-card__date">{date instanceof Date ? format(date, dateFormat ?? 'P', { locale: dateLocale }) : date}</p>
23+
<p className="timeline-card__title">{title}</p>
24+
{children}
25+
</div>
2126
</div>
22-
</div>
23-
);
24-
});
27+
);
28+
},
29+
);

0 commit comments

Comments
 (0)