Skip to content

Commit 2a2dd67

Browse files
authored
refactor: Refactor Notification with pure hooks version (#206)
* chore: init * feat: open & close * chore: base func * test: notification test * test: more test case * test: more test case * docs: Demo update
1 parent 3c1dab4 commit 2a2dd67

21 files changed

+1365
-1026
lines changed

assets/index.less

+91-52
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,136 @@
11
@notificationPrefixCls: rc-notification;
22

33
.@{notificationPrefixCls} {
4+
// ====================== Notification ======================
45
position: fixed;
56
z-index: 1000;
7+
display: flex;
8+
max-height: 100vh;
9+
padding: 10px;
10+
overflow-y: auto;
11+
align-items: flex-end;
612

13+
// Position
14+
&-top,
15+
&-topLeft,
16+
&-topRight {
17+
top: 0;
18+
flex-direction: column;
19+
}
20+
21+
&-topRight {
22+
right: 0;
23+
}
24+
25+
// ========================= Notice =========================
726
&-notice {
8-
padding: 7px 20px 7px 10px;
9-
border-radius: 3px 3px;
10-
border: 1px solid #999;;
11-
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
12-
border: 0px solid rgba(0, 0, 0, 0);;
13-
background: #fff;
27+
position: relative;
1428
display: block;
29+
box-sizing: border-box;
1530
width: auto;
31+
margin: 12px 0;
1632
line-height: 1.5;
17-
position: relative;
18-
margin: 10px 0;
33+
background: #fff;
34+
border: 1px solid #999;
35+
border: 0px solid rgba(0, 0, 0, 0);
36+
border-radius: 3px 3px;
37+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
1938

20-
&-closable {
39+
// Content
40+
&-content {
41+
padding: 7px 20px 7px 10px;
42+
}
43+
44+
&-closable &-content {
2145
padding-right: 20px;
2246
}
2347

2448
&-close {
2549
position: absolute;
26-
right: 5px;
2750
top: 3px;
51+
right: 5px;
2852
color: #000;
29-
cursor: pointer;
30-
outline: none;
31-
font-size: 16px;
3253
font-weight: 700;
54+
font-size: 16px;
3355
line-height: 1;
56+
text-decoration: none;
3457
text-shadow: 0 1px 0 #fff;
58+
outline: none;
59+
cursor: pointer;
60+
opacity: 0.2;
3561
filter: alpha(opacity=20);
36-
opacity: .2;
37-
text-decoration: none;
3862

3963
&-x:after {
4064
content: '×';
4165
}
4266

4367
&:hover {
68+
text-decoration: none;
4469
opacity: 1;
4570
filter: alpha(opacity=100);
46-
text-decoration: none;
4771
}
4872
}
4973
}
5074

51-
.fade-effect() {
52-
animation-duration: 0.3s;
53-
animation-fill-mode: both;
54-
animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2);
75+
&-fade {
76+
overflow: hidden;
77+
transition: all 0.3s;
5578
}
5679

57-
&-fade-appear,
58-
&-fade-enter {
80+
&-fade-appear-start {
81+
transform: translateX(100%);
5982
opacity: 0;
60-
.fade-effect();
61-
animation-play-state: paused;
6283
}
6384

64-
&-fade-leave {
65-
.fade-effect();
66-
animation-play-state: paused;
85+
&-fade-appear-active {
86+
transform: translateX(0);
87+
opacity: 1;
6788
}
6889

69-
&-fade-appear&-fade-appear-active,
70-
&-fade-enter&-fade-enter-active {
71-
animation-name: rcNotificationFadeIn;
72-
animation-play-state: running;
73-
}
90+
// .fade-effect() {
91+
// animation-duration: 0.3s;
92+
// animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2);
93+
// animation-fill-mode: both;
94+
// }
7495

75-
&-fade-leave&-fade-leave-active {
76-
animation-name: rcDialogFadeOut;
77-
animation-play-state: running;
78-
}
96+
// &-fade-appear,
97+
// &-fade-enter {
98+
// opacity: 0;
99+
// animation-play-state: paused;
100+
// .fade-effect();
101+
// }
79102

80-
@keyframes rcNotificationFadeIn {
81-
0% {
82-
opacity: 0;
83-
}
84-
100% {
85-
opacity: 1;
86-
}
87-
}
103+
// &-fade-leave {
104+
// .fade-effect();
105+
// animation-play-state: paused;
106+
// }
88107

89-
@keyframes rcDialogFadeOut {
90-
0% {
91-
opacity: 1;
92-
}
93-
100% {
94-
opacity: 0;
95-
}
96-
}
108+
// &-fade-appear&-fade-appear-active,
109+
// &-fade-enter&-fade-enter-active {
110+
// animation-name: rcNotificationFadeIn;
111+
// animation-play-state: running;
112+
// }
113+
114+
// &-fade-leave&-fade-leave-active {
115+
// animation-name: rcDialogFadeOut;
116+
// animation-play-state: running;
117+
// }
118+
119+
// @keyframes rcNotificationFadeIn {
120+
// 0% {
121+
// opacity: 0;
122+
// }
123+
// 100% {
124+
// opacity: 1;
125+
// }
126+
// }
127+
128+
// @keyframes rcDialogFadeOut {
129+
// 0% {
130+
// opacity: 1;
131+
// }
132+
// 100% {
133+
// opacity: 0;
134+
// }
135+
// }
97136
}

docs/demo/context.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## context
2+
3+
<code src="../examples/context.tsx">

docs/demo/maxCount.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## maxCount
2+
3+
<code src="../examples/maxCount.tsx">

docs/demo/simple.md

-3
This file was deleted.

docs/examples/context.tsx

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* eslint-disable no-console */
2+
import React from 'react';
3+
import '../../assets/index.less';
4+
import { useNotification } from '../../src';
5+
import motion from './motion';
6+
7+
const Context = React.createContext({ name: 'light' });
8+
9+
const NOTICE = {
10+
content: <span>simple show</span>,
11+
onClose() {
12+
console.log('simple close');
13+
},
14+
// duration: null,
15+
};
16+
17+
const Demo = () => {
18+
const [{ open }, holder] = useNotification({ motion });
19+
20+
return (
21+
<Context.Provider value={{ name: 'bamboo' }}>
22+
<button
23+
type="button"
24+
onClick={() => {
25+
open({
26+
...NOTICE,
27+
content: <Context.Consumer>{({ name }) => `Hi ${name}!`}</Context.Consumer>,
28+
props: {
29+
'data-testid': 'my-data-testid',
30+
},
31+
});
32+
}}
33+
>
34+
simple show
35+
</button>
36+
{holder}
37+
</Context.Provider>
38+
);
39+
};
40+
41+
export default Demo;

docs/examples/hooks.tsx

+81-38
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,91 @@
11
/* eslint-disable no-console */
22
import React from 'react';
3-
import Notification from 'rc-notification';
43
import '../../assets/index.less';
5-
import { NotificationInstance } from 'rc-notification/Notification';
4+
import { useNotification } from '../../src';
5+
import motion from './motion';
66

7-
let notificationInstance: NotificationInstance = null;
8-
Notification.newInstance({}, n => {
9-
notificationInstance = n;
10-
});
7+
export default () => {
8+
const [notice, contextHolder] = useNotification({ motion, closable: true });
119

12-
const Context = React.createContext({ name: 'light' });
10+
return (
11+
<>
12+
<div>
13+
<div>
14+
{/* Default */}
15+
<button
16+
onClick={() => {
17+
notice.open({
18+
content: `${new Date().toISOString()}`,
19+
});
20+
}}
21+
>
22+
Basic
23+
</button>
1324

14-
const NOTICE = {
15-
content: <span>simple show</span>,
16-
onClose() {
17-
console.log('simple close');
18-
},
19-
// duration: null,
20-
};
25+
{/* Not Close */}
26+
<button
27+
onClick={() => {
28+
notice.open({
29+
content: `${new Date().toISOString()}`,
30+
duration: null,
31+
});
32+
}}
33+
>
34+
Not Auto Close
35+
</button>
36+
</div>
2137

22-
const Demo = () => {
23-
const [notice, holder] = notificationInstance.useNotification();
38+
<div>
39+
{/* No Closable */}
40+
<button
41+
onClick={() => {
42+
notice.open({
43+
content: `No Close! ${new Date().toISOString()}`,
44+
duration: null,
45+
closable: false,
46+
key: 'No Close',
47+
onClose: () => {
48+
console.log('Close!!!');
49+
},
50+
});
51+
}}
52+
>
53+
No Closable
54+
</button>
2455

25-
return (
26-
<Context.Provider value={{ name: 'bamboo' }}>
27-
<button
28-
type="button"
29-
onClick={() => {
30-
notificationInstance.notice({ ...NOTICE });
31-
notice({
32-
...NOTICE,
33-
content: <Context.Consumer>{({ name }) => `Hi ${name}!`}</Context.Consumer>,
34-
props: {
35-
'data-testid': 'my-data-testid',
36-
},
37-
});
38-
notificationInstance.notice({ ...NOTICE });
39-
}}
40-
>
41-
simple show
42-
</button>
43-
{holder}
44-
</Context.Provider>
56+
{/* Force Close */}
57+
<button
58+
onClick={() => {
59+
notice.close('No Close');
60+
}}
61+
>
62+
Force Close No Closable
63+
</button>
64+
</div>
65+
</div>
66+
67+
<div>
68+
{/* Destroy All */}
69+
<button
70+
onClick={() => {
71+
notice.destroy();
72+
}}
73+
>
74+
Destroy All
75+
</button>
76+
</div>
77+
78+
<div>
79+
{/* Top & Bottom */}
80+
<button
81+
onClick={() => {
82+
notice.destroy();
83+
}}
84+
>
85+
Destroy All
86+
</button>
87+
</div>
88+
{contextHolder}
89+
</>
4590
);
4691
};
47-
48-
export default Demo;

0 commit comments

Comments
 (0)