Skip to content

Commit 87f3bf9

Browse files
use native-time-ago
1 parent 5dc25dd commit 87f3bf9

4 files changed

Lines changed: 33 additions & 72 deletions

File tree

README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33

44
> timeago-react is a simple react component used to format date with `*** time ago` statement. eg: '3 hours ago'.
55
6-
**The component based on [timeago.js](https://github.com/hustcc/timeago.js)** which is a simple javascript module.
6+
**Now uses native-time-ago** - a zero-dependency library using the native Intl.RelativeTimeFormat API.
77

8-
- Realtime render. Automatic release the resources.
9-
- Simple. Only 2kb.
10-
- Efficient. When the time is `3 hour ago`, the interval will an hour (3600 * 1000 ms).
11-
- Locales supported.
8+
- Zero dependencies (uses native Intl.RelativeTimeFormat API)
9+
- Supports 100+ languages automatically via native browser API
10+
- No locale files needed
1211

1312
[![npm](https://img.shields.io/npm/v/timeago-react.svg)](https://www.npmjs.com/package/timeago-react)
1413
[![build](https://github.com/hustcc/timeago-react/workflows/ci/badge.svg)](https://github.com/hustcc/timeago-react)

packages/timeago-react/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@
5959
"typescript-eslint": "^8.26.0",
6060
"vitest": "^3.0.7"
6161
},
62-
"dependencies": {
63-
"timeago.js": "^4.0.0"
62+
"dependencies": {
63+
"native-time-ago": "1.0.1"
6464
},
6565
"peerDependencies": {
6666
"react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"

packages/timeago-react/src/timeago-react.tsx

Lines changed: 26 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,27 @@
11
import * as React from 'react';
2-
import { format, cancel, render } from 'timeago.js';
3-
import { Opts, TDate } from 'timeago.js/lib/interface';
4-
export { Opts, TDate };
5-
6-
/**
7-
* Convert input to a valid datetime string of <time> tag
8-
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time
9-
* @param input
10-
* @returns datetime string
11-
*/
12-
const toDateTime = (input: TDate): string => {
13-
// let date: Date = new Date();
14-
// if (input instanceof Date) {
15-
// date = input;
16-
// //@ts-ignore
17-
// } else if (!isNaN(input) || /^\d+$/.test(input)) {
18-
// //@ts-ignore
19-
// date = new Date(parseInt(input));
20-
// } else {
21-
// date = new Date(input);
22-
// }
23-
24-
// try {
25-
// return date.toISOString();
26-
// } catch (e) {
27-
// console.error('invalid datetime');
28-
// return '';
29-
// }
2+
import timeAgo from 'native-time-ago';
303

4+
const toDateTime = (input: any): string => {
315
return '' + (input instanceof Date ? input.getTime() : input);
326
};
337

34-
// These ts-ignores are to import types from different React versions
35-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
36-
// @ts-ignore
37-
export interface TimeAgoProps
38-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
39-
// @ts-ignore
40-
extends React.ComponentProps<'time'>,
41-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
42-
// @ts-ignore
43-
React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>,
44-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
45-
// @ts-ignore
46-
React.HTMLProps<HTMLTimeElement> {
47-
readonly datetime: TDate; // date to be formatted
48-
readonly live?: boolean; // real time render.
49-
readonly opts?: Opts;
50-
readonly locale?: string; // locale lang
8+
export interface TimeAgoProps extends React.HTMLAttributes<HTMLTimeElement> {
9+
readonly datetime: any;
10+
readonly live?: boolean;
11+
readonly opts?: any; // Not supported in native-time-ago
12+
readonly locale?: string;
5113
}
5214

5315
export default class TimeAgo extends React.PureComponent<TimeAgoProps, unknown> {
5416
static defaultProps = {
55-
live: true,
17+
live: false,
5618
className: '',
5719
};
5820

5921
dom: HTMLTimeElement = null;
22+
intervalId: ReturnType<typeof setInterval> = null;
6023

6124
componentDidMount(): void {
62-
// fixed #6 https://github.com/hustcc/timeago-react/issues/6
63-
// to reduce the file size.
64-
// const { locale } = this.props;
65-
// if (locale !== 'en' && locale !== 'zh_CN') {
66-
// timeago.register(locale, require('timeago.js/locales/' + locale));
67-
// }
68-
// render it.
6925
this.renderTimeAgo();
7026
}
7127

@@ -74,26 +30,31 @@ export default class TimeAgo extends React.PureComponent<TimeAgoProps, unknown>
7430
}
7531

7632
renderTimeAgo(): void {
77-
const { live, datetime, locale, opts } = this.props;
78-
// cancel all the interval
79-
cancel(this.dom);
80-
// if is live
33+
const { live, datetime, locale } = this.props;
34+
if (this.intervalId) {
35+
clearInterval(this.intervalId);
36+
this.intervalId = null;
37+
}
8138
if (live !== false) {
82-
// live render
8339
this.dom.setAttribute('datetime', toDateTime(datetime));
84-
85-
render(this.dom, locale, opts);
40+
const update = () => {
41+
if (this.dom) {
42+
this.dom.textContent = timeAgo(datetime, locale || 'en');
43+
}
44+
};
45+
update();
46+
this.intervalId = setInterval(update, 60000);
8647
}
8748
}
8849

89-
// remove
9050
componentWillUnmount(): void {
91-
cancel(this.dom);
51+
if (this.intervalId) {
52+
clearInterval(this.intervalId);
53+
this.intervalId = null;
54+
}
9255
}
9356

94-
// for render
9557
render(): React.JSX.Element {
96-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
9758
const { datetime, live, locale, opts, ...others } = this.props;
9859
return (
9960
<time
@@ -102,7 +63,7 @@ export default class TimeAgo extends React.PureComponent<TimeAgoProps, unknown>
10263
}}
10364
{...others}
10465
>
105-
{format(datetime, locale, opts)}
66+
{timeAgo(datetime, locale || 'en')}
10667
</time>
10768
);
10869
}

packages/timeago-react/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"sourceMap": true,
88
"pretty": true,
99
"lib": ["dom", "esnext"],
10+
"esModuleInterop": true
1011
},
1112
"include": ["src/**/*"],
1213
"exclude": ["node_modules"]

0 commit comments

Comments
 (0)