Skip to content

Commit f7ad149

Browse files
committed
Merge branch 'release/0.2.14'
2 parents 7731449 + 3d6e955 commit f7ad149

11 files changed

+136
-35
lines changed

.eslintrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
}
1818
},
1919
"rules": {
20-
"react/display-name": 2,
20+
"react/display-name": 0,
2121
"react/jsx-curly-spacing": [2, "always"],
2222
"react/jsx-no-duplicate-props": 2,
2323
"react/jsx-no-undef": 2,

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# CHANGELOG
22

3+
## 0.2.14 - May 3, 2017
4+
5+
* Ability to [edit notifications](https://github.com/igorprado/react-notification-system#removenotificationnotification). (thanks to @syndbg)
6+
* Removed deprecation warning. Now using `prop-types` and `create-react-class`packages. (thanks to @andrewBalekha)
7+
* Fix calling `onRemove` before updating the notifications state. (thanks to @szdc)
8+
39
## 0.2.13 - Mar 14, 2017
410

511
* UMD support. (thanks to @jochenberger)

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ Returns the notification object to be used to programmatically dismiss a notific
8686

8787
Remove a notification programmatically. You can pass an object returned by `addNotification()` or by `onAdd()` callback. If passing an object, you need to make sure it must contain the `uid` property. You can pass only the `uid` too: `removeNotification(uid)`.
8888

89+
90+
### `editNotification(notification)`
91+
92+
Edit a notification programmatically. You can pass an object previously returned by `addNotification()` or by `onAdd()` callback. If passing an object, you need to make sure it must contain the `uid` property. You can pass only the `uid` too: `editNotification(uid)`.
93+
94+
8995
### `clearNotifications()`
9096

9197
Removes ALL notifications programatically.

example/src/scripts/App.jsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var React = require('react');
22
var ReactDOM = require('react-dom');
3+
var createReactClass = require('create-react-class');
34
var NotificationSystem = require('NotificationSystem');
45
var constants = require('constants');
56
var NotificationGenerator = require('./NotificationGenerator');
@@ -14,7 +15,7 @@ var _getRandomPosition = function() {
1415
// Styles
1516
require('styles/base');
1617

17-
NotificationSystemExample = React.createClass({
18+
NotificationSystemExample = createReactClass({
1819

1920
displayName: 'App',
2021

example/src/scripts/CustomElement.jsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var React = require('react');
2+
var PropTypes = require('prop-types');
23

34
function buttonClicked() {
45
alert('I\'m a custom button inside a custom element that was clicked');
@@ -14,7 +15,7 @@ function CustomElement(props) {
1415
}
1516

1617
CustomElement.propTypes = {
17-
name: React.PropTypes.string
18+
name: PropTypes.string
1819
};
1920

2021
module.exports = CustomElement;

example/src/scripts/NotificationGenerator.jsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
var React = require('react');
2+
var createReactClass = require('create-react-class');
3+
var PropTypes = require('prop-types');
24

35
// Styles
46
require('styles/generator');
57

6-
module.exports = React.createClass({
8+
module.exports = createReactClass({
79

810
displayName: 'NotificationGenerator',
911

@@ -134,8 +136,8 @@ module.exports = React.createClass({
134136
},
135137

136138
propTypes: {
137-
notifications: React.PropTypes.func.isRequired,
138-
allowHTML: React.PropTypes.func
139+
notifications: PropTypes.func.isRequired,
140+
allowHTML: PropTypes.func
139141
},
140142

141143
render: function() {

package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-notification-system",
3-
"version": "0.2.13",
3+
"version": "0.2.14",
44
"description": "A React Notification System fully customized",
55
"main": "dist/NotificationSystem.js",
66
"scripts": {
@@ -32,7 +32,9 @@
3232
},
3333
"homepage": "https://github.com/igorprado/react-notification-system",
3434
"dependencies": {
35-
"object-assign": "^4.0.1"
35+
"create-react-class": "^15.5.1",
36+
"object-assign": "^4.0.1",
37+
"prop-types": "^15.5.6"
3638
},
3739
"peerDependencies": {
3840
"react": "0.14.x || ^15.0.0",

src/NotificationContainer.jsx

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
var React = require('react');
2+
var createReactClass = require('create-react-class');
3+
var PropTypes = require('prop-types');
24
var NotificationItem = require('./NotificationItem');
35
var Constants = require('./constants');
46

5-
var NotificationContainer = React.createClass({
7+
var NotificationContainer = createReactClass({
68

79
propTypes: {
8-
position: React.PropTypes.string.isRequired,
9-
notifications: React.PropTypes.array.isRequired,
10-
getStyles: React.PropTypes.object
10+
position: PropTypes.string.isRequired,
11+
notifications: PropTypes.array.isRequired,
12+
getStyles: PropTypes.object
1113
},
1214

1315
_style: {},

src/NotificationItem.jsx

+11-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
var React = require('react');
2+
var createReactClass = require('create-react-class');
3+
var PropTypes = require('prop-types');
24
var ReactDOM = require('react-dom');
35
var Constants = require('./constants');
46
var Helpers = require('./helpers');
@@ -24,17 +26,17 @@ var whichTransitionEvent = function() {
2426
return transition;
2527
};
2628

27-
var NotificationItem = React.createClass({
29+
var NotificationItem = createReactClass({
2830

2931
propTypes: {
30-
notification: React.PropTypes.object,
31-
getStyles: React.PropTypes.object,
32-
onRemove: React.PropTypes.func,
33-
allowHTML: React.PropTypes.bool,
34-
noAnimation: React.PropTypes.bool,
35-
children: React.PropTypes.oneOfType([
36-
React.PropTypes.string,
37-
React.PropTypes.element
32+
notification: PropTypes.object,
33+
getStyles: PropTypes.object,
34+
onRemove: PropTypes.func,
35+
allowHTML: PropTypes.bool,
36+
noAnimation: PropTypes.bool,
37+
children: PropTypes.oneOfType([
38+
PropTypes.string,
39+
PropTypes.element
3840
])
3941
},
4042

src/NotificationSystem.jsx

+61-14
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
var React = require('react');
2+
var createReactClass = require('create-react-class');
3+
var PropTypes = require('prop-types');
24
var merge = require('object-assign');
35
var NotificationContainer = require('./NotificationContainer');
46
var Constants = require('./constants');
57
var Styles = require('./styles');
68

7-
var NotificationSystem = React.createClass({
9+
var NotificationSystem = createReactClass({
810

911
uid: 3400,
1012

@@ -66,17 +68,18 @@ var NotificationSystem = React.createClass({
6668
var notifications = this.state.notifications.filter(function(toCheck) {
6769
if (toCheck.uid === uid) {
6870
notification = toCheck;
71+
return false;
6972
}
70-
return toCheck.uid !== uid;
73+
return true;
7174
});
7275

73-
if (notification && notification.onRemove) {
74-
notification.onRemove(notification);
75-
}
76-
7776
if (this._isMounted) {
7877
this.setState({ notifications: notifications });
7978
}
79+
80+
if (notification && notification.onRemove) {
81+
notification.onRemove(notification);
82+
}
8083
},
8184

8285
getInitialState: function() {
@@ -86,12 +89,12 @@ var NotificationSystem = React.createClass({
8689
},
8790

8891
propTypes: {
89-
style: React.PropTypes.oneOfType([
90-
React.PropTypes.bool,
91-
React.PropTypes.object
92+
style: PropTypes.oneOfType([
93+
PropTypes.bool,
94+
PropTypes.object
9295
]),
93-
noAnimation: React.PropTypes.bool,
94-
allowHTML: React.PropTypes.bool
96+
noAnimation: PropTypes.bool,
97+
allowHTML: PropTypes.bool
9598
},
9699

97100
getDefaultProps: function() {
@@ -152,18 +155,63 @@ var NotificationSystem = React.createClass({
152155
return _notification;
153156
},
154157

155-
removeNotification: function(notification) {
158+
getNotificationRef: function(notification) {
156159
var self = this;
160+
var foundNotification = null;
161+
157162
Object.keys(this.refs).forEach(function(container) {
158163
if (container.indexOf('container') > -1) {
159164
Object.keys(self.refs[container].refs).forEach(function(_notification) {
160165
var uid = notification.uid ? notification.uid : notification;
161166
if (_notification === 'notification-' + uid) {
162-
self.refs[container].refs[_notification]._hideNotification();
167+
// NOTE: Stop iterating further and return the found notification.
168+
// Since UIDs are uniques and there won't be another notification found.
169+
foundNotification = self.refs[container].refs[_notification];
170+
return;
163171
}
164172
});
165173
}
166174
});
175+
176+
return foundNotification;
177+
},
178+
179+
removeNotification: function(notification) {
180+
var foundNotification = this.getNotificationRef(notification);
181+
return foundNotification && foundNotification._hideNotification();
182+
},
183+
184+
editNotification: function(notification, newNotification) {
185+
var foundNotification = null;
186+
// NOTE: Find state notification to update by using
187+
// `setState` and forcing React to re-render the component.
188+
var uid = notification.uid ? notification.uid : notification;
189+
190+
var newNotifications = this.state.notifications.filter(function(stateNotification) {
191+
if (uid === stateNotification.uid) {
192+
foundNotification = stateNotification;
193+
return false;
194+
}
195+
196+
return true;
197+
});
198+
199+
200+
if (!foundNotification) {
201+
return;
202+
}
203+
204+
newNotifications.push(
205+
merge(
206+
{},
207+
foundNotification,
208+
newNotification
209+
)
210+
);
211+
212+
this.setState({
213+
notifications: newNotifications
214+
});
167215
},
168216

169217
clearNotifications: function() {
@@ -221,7 +269,6 @@ var NotificationSystem = React.createClass({
221269
<div className="notifications-wrapper" style={ this._getStyles.wrapper() }>
222270
{ containers }
223271
</div>
224-
225272
);
226273
}
227274
});

test/notification-system.test.js

+32
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,38 @@ describe('Notification Component', function() {
172172
done();
173173
});
174174

175+
it('should edit an existing notification using returned object', (done) => {
176+
const notificationCreated = component.addNotification(defaultNotification);
177+
const notification = TestUtils.scryRenderedDOMComponentsWithClass(instance, 'notification');
178+
expect(notification.length).toEqual(1);
179+
180+
const newTitle = 'foo';
181+
const newContent = 'foobar';
182+
183+
component.editNotification(notificationCreated, { title: newTitle, message: newContent });
184+
clock.tick(1000);
185+
const notificationEdited = TestUtils.findRenderedDOMComponentWithClass(instance, 'notification');
186+
expect(notificationEdited.getElementsByClassName('notification-title')[0].textContent).toEqual(newTitle);
187+
expect(notificationEdited.getElementsByClassName('notification-message')[0].textContent).toEqual(newContent);
188+
done();
189+
});
190+
191+
it('should edit an existing notification using uid', (done) => {
192+
const notificationCreated = component.addNotification(defaultNotification);
193+
const notification = TestUtils.scryRenderedDOMComponentsWithClass(instance, 'notification');
194+
expect(notification.length).toEqual(1);
195+
196+
const newTitle = 'foo';
197+
const newContent = 'foobar';
198+
199+
component.editNotification(notificationCreated.uid, { title: newTitle, message: newContent });
200+
clock.tick(1000);
201+
const notificationEdited = TestUtils.findRenderedDOMComponentWithClass(instance, 'notification');
202+
expect(notificationEdited.getElementsByClassName('notification-title')[0].textContent).toEqual(newTitle);
203+
expect(notificationEdited.getElementsByClassName('notification-message')[0].textContent).toEqual(newContent);
204+
done();
205+
});
206+
175207
it('should remove all notifications', done => {
176208
component.addNotification(defaultNotification);
177209
component.addNotification(defaultNotification);

0 commit comments

Comments
 (0)