Skip to content

Commit c8bfa52

Browse files
committed
feat(common): add component, helpers & hooks to common libs
1 parent dbb1157 commit c8bfa52

33 files changed

Lines changed: 1311 additions & 18 deletions

File tree

libs/common/README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
# common
1+
# @crudx/common
22

3-
This library was generated with [Nx](https://nx.dev).
3+
This library is contains common helpers, hooks & components
44

5-
## Running unit tests
5+
---
66

7-
Run `nx test common` to execute the unit tests via [Jest](https://jestjs.io).
7+
## Installation
8+
9+
```bash
10+
yarn add @crudx/common dayjs numeral react react-dom
11+
```

libs/common/project.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
"tsConfig": "libs/common/tsconfig.lib.json",
2121
"project": "libs/common/package.json",
2222
"entryFile": "libs/common/src/index.ts",
23-
"external": ["react", "react-dom", "react/jsx-runtime"],
2423
"rollupConfig": "@nx/react/plugins/bundle-rollup",
2524
"compiler": "babel",
25+
"format": ["cjs", "esm"],
26+
"external": ["dayjs", "numeral", "react", "react-dom"],
2627
"assets": [
2728
{
2829
"glob": "libs/common/README.md",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# CloneElement
2+
3+
Inject props to target component
4+
5+
## Props
6+
7+
```TypeScript
8+
{
9+
[key: string]: any;
10+
};
11+
```
12+
13+
---
14+
15+
## Example
16+
17+
```TypeScript
18+
// import from package
19+
import { CloneElement } from "@crudx/common";
20+
21+
// example of component
22+
const Button = (props) => {
23+
const :{ children, ...restProps } = props;
24+
return <button {...restProps}>{children}</button>
25+
}
26+
27+
// usage
28+
<CloneElement
29+
onClick={() => {
30+
console.log('do something')
31+
}}
32+
>
33+
<Button>Testing</Button>
34+
</CloneElement>,
35+
```
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
3+
import { CloneElementProps } from './props';
4+
5+
/**
6+
* ===========================
7+
* MAIN
8+
* ===========================
9+
*/
10+
export const CloneElement: React.FC<CloneElementProps> = (props) => {
11+
const { children, ...restProps } = props;
12+
13+
// =============== VIEW
14+
const childrenWithProps = React.Children.map(children, (child: any) => {
15+
if (!child || typeof child === 'boolean') {
16+
return null;
17+
}
18+
return React.cloneElement(child, restProps);
19+
});
20+
21+
return childrenWithProps;
22+
};
23+
24+
/**
25+
* ===========================
26+
* EXPORTS
27+
* ===========================
28+
*/
29+
export * from './props';
30+
export default CloneElement;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* ===========================
3+
* MAIN
4+
* ===========================
5+
*/
6+
export type CloneElementProps = {
7+
[key: string]: any;
8+
};
9+
10+
/**
11+
* ===========================
12+
* EXPORTS
13+
* ===========================
14+
*/
15+
export default CloneElementProps;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# DateTime
2+
3+
This component help to display date time easily
4+
5+
## Props
6+
7+
```TypeScript
8+
type DateTimeProps = {
9+
/**
10+
* date object or date string
11+
*/
12+
date?: any;
13+
/**
14+
* display format, `date`, `datetime` is preset, otherwise custom format
15+
* default to `datetime`
16+
*/
17+
kind?: 'date' | 'date2' | 'datetime' | string;
18+
/**
19+
* the date format, will take place if provided
20+
*/
21+
format?: string;
22+
/**
23+
* whether should display relative time
24+
* default `false`
25+
*/
26+
relative?: boolean;
27+
/**
28+
* set locale time
29+
*/
30+
locale?: string;
31+
/**
32+
* prefix of time
33+
*/
34+
prefix?: ReactNode;
35+
/**
36+
* postfix of time
37+
*/
38+
postfix?: ReactNode;
39+
}
40+
```
41+
42+
---
43+
44+
## Example
45+
46+
```TypeScript
47+
// import from package
48+
import { DateTime } from "@crudx/common";
49+
50+
const date = new Date();
51+
52+
// simple usage
53+
<DateTime date={date} />
54+
55+
// with kind
56+
// kind `date`, "DD, MMM YYYY"
57+
<DateTime date={date} kind="date" />
58+
59+
// kind `datetime`, "Do, MMM YYYY hh:mm:A"
60+
<DateTime date={date} kind="datetime" />
61+
62+
// kind `custom`, refer to this https://day.js.org/docs/en/display/format
63+
<DateTime date={date} kind="D (ddd) MMM, YYYY"/>
64+
65+
// relative time - example `1 hours ago`
66+
<DateTime date={date} relative={true} />
67+
```
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import dayjs from 'dayjs';
2+
3+
/**
4+
* ===========================
5+
* MAIN
6+
* ===========================
7+
*/
8+
// function to calculate next update
9+
export const calculateNextUpdate = (date) => {
10+
const now = dayjs();
11+
const diffInSeconds = now.diff(date, 'second');
12+
13+
if (diffInSeconds < 60) {
14+
// less than a minute ago, update every 5 seconds
15+
return 5000;
16+
} else if (diffInSeconds < 3600) {
17+
// less than an hour ago, update every 30 seconds
18+
return 30000;
19+
} else if (diffInSeconds < 86400) {
20+
// less than a day ago, update every 5 minutes
21+
return 300000;
22+
} else {
23+
// more than a day ago, update every hour
24+
return 3600000;
25+
}
26+
};
27+
28+
/**
29+
* ===========================
30+
* EXPORTS
31+
* ===========================
32+
*/
33+
export default { calculateNextUpdate };
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React, { useEffect, useMemo, useState } from 'react';
2+
3+
import { formatDateTime } from '../../helpers/date';
4+
5+
import { calculateNextUpdate } from './helpers';
6+
import { DateTimeProps } from './props';
7+
8+
/**
9+
* ===========================
10+
* MAIN
11+
* ===========================
12+
*/
13+
export const DateTime: React.FC<DateTimeProps> = (props) => {
14+
const {
15+
date,
16+
kind = 'datetime',
17+
format,
18+
prefix,
19+
postfix,
20+
...restProps
21+
} = props;
22+
23+
// =============== STATE
24+
const [tick, setTick] = useState(0);
25+
const [datetime, setDateTime] = useState('');
26+
27+
// =============== HELPERS
28+
// function to get date format
29+
const finalFormat = useMemo(() => {
30+
if (format) return format;
31+
if (kind === 'date') {
32+
return 'DD, MMM YYYY';
33+
}
34+
if (kind === 'date2') {
35+
return 'DD-MM-YYYY';
36+
}
37+
if (kind === 'datetime') {
38+
return 'Do, MMM YYYY hh:mm:A';
39+
}
40+
return 'DD, MMM YYYY';
41+
}, [format, kind]);
42+
43+
// =============== EFFECTS
44+
useEffect(() => {
45+
const time = formatDateTime(date, { format: finalFormat, ...restProps });
46+
setDateTime(time);
47+
}, [date, finalFormat, restProps]);
48+
49+
useEffect(() => {
50+
const updateInterval = calculateNextUpdate(date);
51+
const timeoutId = setTimeout(() => {
52+
if (!restProps.relative) return;
53+
setDateTime(formatDateTime(date, { format: finalFormat, ...restProps }));
54+
setTick(tick + 1);
55+
}, updateInterval);
56+
return () => clearTimeout(timeoutId);
57+
}, [date, tick, finalFormat, restProps]);
58+
59+
// =============== VIEWS
60+
return (
61+
<>
62+
{prefix}
63+
{datetime}
64+
{postfix}
65+
</>
66+
);
67+
};
68+
69+
/**
70+
* ===========================
71+
* EXPORT
72+
* ===========================
73+
*/
74+
export * from './props';
75+
export default DateTime;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { ReactNode } from 'react';
2+
3+
/**
4+
* ===========================
5+
* MAIN
6+
* ===========================
7+
*/
8+
export type DateTimeProps = {
9+
/**
10+
* date object or date string
11+
*/
12+
date?: any;
13+
/**
14+
* display format, `date`, `datetime` is preset, otherwise custom format
15+
* default to `datetime`
16+
*/
17+
kind?: 'date' | 'date2' | 'datetime' | string;
18+
/**
19+
* the date format, will take place if provided
20+
*/
21+
format?: string;
22+
/**
23+
* whether should display relative time
24+
* default `false`
25+
*/
26+
relative?: boolean;
27+
/**
28+
* set locale time
29+
*/
30+
locale?: string;
31+
/**
32+
* prefix of time
33+
*/
34+
prefix?: ReactNode;
35+
/**
36+
* postfix of time
37+
*/
38+
postfix?: ReactNode;
39+
};
40+
41+
/**
42+
* ===========================
43+
* EXPORT
44+
* ===========================
45+
*/
46+
export default DateTimeProps;

0 commit comments

Comments
 (0)