react-notification
Advanced tools
Comparing version 5.0.3 to 5.0.4
@@ -43,4 +43,4 @@ 'use strict'; | ||
value: function componentWillReceiveProps(nextProps) { | ||
if (nextProps.onDismiss && this.props.onDismiss === nextProps.onDismiss && nextProps.isActive && !this.props.isActive) { | ||
clearTimeout(this.dismissTimeout); | ||
if (!nextProps.hasOwnProperty('isLast')) clearTimeout(this.dismissTimeout); | ||
if (nextProps.onDismiss && nextProps.isActive && !this.props.isActive) { | ||
this.dismissTimeout = setTimeout(nextProps.onDismiss, nextProps.dismissAfter); | ||
@@ -47,0 +47,0 @@ } |
@@ -41,7 +41,3 @@ 'use strict'; | ||
dismissAfter: isLast ? dismissAfter : dismissAfter + index * 1000, | ||
onDismiss: function onDismiss() { | ||
setTimeout(function () { | ||
setTimeout(props.onDismiss.bind(undefined, notification), 300); | ||
}, 300); | ||
}, | ||
onDismiss: props.onDismiss.bind(undefined, notification), | ||
index: index | ||
@@ -48,0 +44,0 @@ })); |
@@ -56,2 +56,3 @@ 'use strict'; | ||
clearTimeout(this.dismissTimeout); | ||
clearTimeout(this.dismissTimeout); | ||
} | ||
@@ -61,5 +62,10 @@ }, { | ||
value: function render() { | ||
var _this2 = this; | ||
var bottomPosition = 2 + this.props.index * 4 + 'rem'; | ||
return _react2.default.createElement(_notification2.default, _extends({}, this.props, { | ||
onDismiss: function onDismiss() { | ||
return setTimeout(_this2.props.onDismiss, 300); | ||
}, | ||
isActive: this.state.isActive, | ||
@@ -66,0 +72,0 @@ barStyle: Object.assign({}, { |
@@ -11,7 +11,10 @@ import React, { Component } from 'react'; | ||
this.state = { | ||
notifications: {}, | ||
notifications: OrderedSet(), | ||
// This is just used for the sake of an example to make sure | ||
// notifications have unique keys. In production, you should have | ||
// a different system for UIDs. | ||
count: 0 | ||
}; | ||
this.removeNotification = this.removeNotification.bind(this); | ||
this.renderNotifications = this.renderNotifications.bind(this); | ||
} | ||
@@ -21,34 +24,25 @@ | ||
addNotification() { | ||
// This is just used for the sake of an example to make sure | ||
// notifications have unique keys. In production, you should have | ||
// a different system for UIDs. | ||
const id = Date.now(); | ||
const notifications = Object.assign({}, this.state.notifications, { | ||
[id]: { | ||
const { notifications, count } = this.state; | ||
const id = notifications.size + 1; | ||
const newCount = count + 1; | ||
return this.setState({ | ||
count: newCount, | ||
notifications: notifications.add({ | ||
message: `Notification ${id}`, | ||
key: newCount, | ||
action: 'Dismiss', | ||
dismissAfter: 3400, | ||
onClick: () => this.removeNotification(id), | ||
message: `Notification ${id}`, | ||
key: id | ||
} | ||
onClick: () => this.removeNotification(newCount), | ||
}) | ||
}); | ||
return this.setState({ | ||
notifications: notifications | ||
}); | ||
} | ||
removeNotification (notif) { | ||
const notifications = Object.assign({}, this.state.notifications); | ||
delete notifications[notif]; | ||
this.setState({ notifications }) | ||
removeNotification (count) { | ||
const { notifications } = this.state; | ||
this.setState({ | ||
notifications: notifications.filter(n => n.key !== count) | ||
}) | ||
} | ||
renderNotifications () { | ||
return Object.keys(this.state.notifications).map(notif => this.state.notifications[notif]) | ||
} | ||
render() { | ||
render () { | ||
return ( | ||
@@ -60,4 +54,6 @@ <div> | ||
<NotificationStack | ||
notifications={this.renderNotifications()} | ||
onDismiss={notif => this.removeNotification(notif.key)} | ||
notifications={this.state.notifications.toArray()} | ||
onDismiss={notification => this.setState({ | ||
notifications: this.state.notifications.delete(notification) | ||
})} | ||
/> | ||
@@ -64,0 +60,0 @@ </div> |
{ | ||
"name": "react-notification", | ||
"version": "5.0.3", | ||
"version": "5.0.4", | ||
"description": "Snackbar style notification component for React.", | ||
@@ -49,3 +49,4 @@ "main": "dist/index.js", | ||
"html-webpack-plugin": "^2.10.0", | ||
"immutable": "^3.7.6", | ||
"immutable": "^3.8.1", | ||
"jsdom": "^8.5.0", | ||
"mocha": "^2.4.5", | ||
@@ -52,0 +53,0 @@ "react": "^0.14.7", |
@@ -20,2 +20,4 @@ # react-notification | ||
Note the component uses `Object.assign`. If you are compiling with Babel, you should include the Babel Polyfill in your build to ensure the method works. | ||
## Usage | ||
@@ -42,11 +44,28 @@ | ||
state = { | ||
notifications: OrderedSet().add({ | ||
message: 'Notification message' | ||
key: 'some UID' | ||
constructor () { | ||
super(); | ||
this.state = { | ||
notifications: OrderedSet() | ||
}; | ||
} | ||
addNotification () { | ||
const newCount = count + 1; | ||
return this.setState({ | ||
notifications: this.state.notifications.add({ | ||
message: `Notification ipsum...`, | ||
key: 'some UID', | ||
action: 'Dismiss', | ||
onClick: () => this.removeNotification('some UID'), | ||
}) | ||
}); | ||
} | ||
removeNotification (count) { | ||
this.setState({ | ||
notifications: this.state.notifications.filter(n => n.key !== count) | ||
}) | ||
} | ||
// Using immutable.js for the array of notifications | ||
render() { | ||
render () { | ||
return ( | ||
@@ -63,3 +82,3 @@ <NotificationStack | ||
See the examples for more context on how to use a notification stack. | ||
See the [examples](/examples/notification-tree) for more context on how to use a notification stack. | ||
@@ -92,3 +111,3 @@ ### Props | ||
**Note notifications used in a stack can not have actions and require a unique key property. All other properties included in the regular notification component are supported.** | ||
**Update** `v5.0.3`: Now notifications used in a stack _can_ have all properties included in the regular notification component. | ||
@@ -95,0 +114,0 @@ ## Events |
@@ -118,2 +118,47 @@ import { Notification, NotificationStack } from '../src/index'; | ||
}); | ||
it('onDismiss does not fire before `dismissAfter` value times out', done => { | ||
const handleDismiss = spy(); | ||
const wrapper = mount( | ||
<Notification | ||
message={mockNotification.message} | ||
dismissAfter={mockNotification.dismissAfter} | ||
onDismiss={handleDismiss} | ||
/> | ||
); | ||
expect(handleDismiss.calledOnce).to.equal(false); | ||
wrapper.setProps({ isActive: true }); | ||
setTimeout(() => { | ||
try { | ||
expect(handleDismiss.calledOnce).to.equal(false); | ||
done(); | ||
} catch (e) { | ||
done(e); | ||
} | ||
}, mockNotification.dismissAfter / 2); | ||
}); | ||
it('onDismiss fires after `dismissAfter` value times out', done => { | ||
const handleDismiss = spy(); | ||
const wrapper = mount( | ||
<Notification | ||
message={mockNotification.message} | ||
dismissAfter={mockNotification.dismissAfter} | ||
onDismiss={handleDismiss} | ||
/> | ||
); | ||
wrapper.setProps({ isActive: true }); | ||
setTimeout(() => { | ||
try { | ||
expect(handleDismiss.calledOnce).to.equal(true); | ||
done(); | ||
} catch (e) { | ||
done(e); | ||
} | ||
}, mockNotification.dismissAfter); | ||
}); | ||
}); |
@@ -5,15 +5,53 @@ import { Notification, NotificationStack } from '../src/index'; | ||
describe('<NotificationStack />', () => { | ||
it('onDismiss fires once', () => { | ||
let notifications; | ||
beforeEach(() => { | ||
notifications = [ | ||
mockNotification, | ||
Object.assign({}, mockNotification, { key: 2222 }) | ||
]; | ||
}); | ||
it('onDismiss fires after `dismissAfter` value + transition time', done => { | ||
const handleDismiss = spy(); | ||
const wrapper = shallow( | ||
const wrapper = mount( | ||
<NotificationStack | ||
notifications={[mockNotification]} | ||
notifications={notifications} | ||
onDismiss={handleDismiss} | ||
/> | ||
); | ||
wrapper.update(); | ||
setTimeout(() => { | ||
try { | ||
expect(handleDismiss.calledOnce).to.equal(true); | ||
done(); | ||
} catch (e) { | ||
done(e); | ||
} | ||
// Add time due to each StackedNotification transition time ( > 300 ) | ||
}, mockNotification.dismissAfter + 340); | ||
}); | ||
it('onDismiss fires on each Notification in the stack', done => { | ||
const handleDismiss = spy(); | ||
const wrapper = mount( | ||
<NotificationStack | ||
notifications={notifications} | ||
onDismiss={handleDismiss} | ||
/> | ||
); | ||
wrapper.update(); | ||
setTimeout(() => { | ||
expect(handleDismiss.calledOnce).to.equal(true); | ||
}, mockNotification.dismissAfter); | ||
try { | ||
expect(handleDismiss.callCount).to.equal(notifications.length); | ||
done(); | ||
} catch (e) { | ||
done(e); | ||
} | ||
// Add transition time + 1000ms per each Notification | ||
}, mockNotification.dismissAfter + 1340); | ||
}); | ||
@@ -20,0 +58,0 @@ |
@@ -12,3 +12,20 @@ import chai from 'chai'; | ||
global.shallow = require('enzyme').shallow; | ||
global.mount = require('enzyme').mount; | ||
global.jsdom = require('jsdom').jsdom; | ||
var exposedProperties = ['window', 'navigator', 'document']; | ||
global.document = jsdom(''); | ||
global.window = document.defaultView; | ||
Object.keys(document.defaultView).forEach((property) => { | ||
if (typeof global[property] === 'undefined') { | ||
exposedProperties.push(property); | ||
global[property] = document.defaultView[property]; | ||
} | ||
}); | ||
global.navigator = { | ||
userAgent: 'node.js' | ||
}; | ||
chai.use(chaiEnzyme()); |
358407
710
151
26