Skip to content
This repository was archived by the owner on Dec 24, 2019. It is now read-only.

Commit 4917d99

Browse files
Berkeley MartinezPatrick Burtchaell
authored andcommitted
Dynamically control bar bottom value
Adds the ability to pass in a function for either `barStyle` or `activeBarStyle` props on the NotificationStack component. This makes the bottom css value controllable by the user. closes #57
1 parent bdec4e2 commit 4917d99

File tree

4 files changed

+118
-13
lines changed

4 files changed

+118
-13
lines changed

README.md

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,11 @@ The `style` prop useful if you are not using React inline styles and would like
101101

102102
For NotificationStack component:
103103

104-
| Name | Type | Description | Required | Default |
105-
|----------------|-------|----------------------------------------------|---------- |----------|
106-
| notifications | array | Array of notifications to render | true | |
104+
| Name | Type | Description | Required | Default |
105+
|-----------------------|-------|----------------------------------------------|---------- |----------|
106+
| notifications | array | Array of notifications to render | true | |
107+
| barStyleFactory | func | create the style of the notification | false | fn |
108+
| activeBarStyleFactory | func | create the style of the active notification | false | fn |
107109

108110
**Update** `v5.0.3`: Now notifications used in a stack _can_ have all properties included in the regular notification component.
109111

@@ -144,6 +146,31 @@ To use additional inline styles, return two objects. The `bar` object applies st
144146

145147
I would highly suggest using this method since the styles included in the component by default handle the visibility of the notification. If you remove these styles, the component won't actually show or hide itself.
146148

149+
### barStyleFactory and activeBarStyleFactory NotificationStack props
150+
151+
These two function have the following signature:
152+
153+
```js
154+
(index: Number, style: Object|Void) => Object
155+
```
156+
157+
Where `index` is the index of the notification in the notifications array and
158+
`style` is the style property of the individual notification.
159+
160+
This function is used to dynamically set the style of each notification in the
161+
stack. The default function adds the `bottom` style property to correctly
162+
position of the notification in a stack.
163+
164+
```js
165+
function defaultStyleFactory(index, style) {
166+
return Object.assign(
167+
{},
168+
style,
169+
{ bottom: `${2 + index * 4}rem` }
170+
);
171+
}
172+
```
173+
147174
---
148175
Built with care in New Orleans by [Patrick Burtchaell](http://twitter.com/pburtchaell).
149176

src/notificationStack.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ import React, { PropTypes } from 'react';
22
import defaultPropTypes from './defaultPropTypes';
33
import StackedNotification from './stackedNotification';
44

5+
function defaultStyleFactory(index, style) {
6+
return Object.assign(
7+
{},
8+
style,
9+
{ bottom: `${2 + index * 4}rem` }
10+
);
11+
}
12+
513
/**
614
* The notification list does not have any state, so use a
715
* pure function here. It just needs to return the stacked array
@@ -13,6 +21,11 @@ const NotificationStack = props => {
1321
{props.notifications.map((notification, index) => {
1422
const dismissAfter = notification.dismissAfter || props.dismissAfter;
1523
const isLast = index === 0 && props.notifications.length === 1;
24+
const barStyle = props.barStyleFactory(index, notification.barStyle);
25+
const activeBarStyle = props.activeBarStyleFactory(
26+
index,
27+
notification.activeBarStyle
28+
);
1629

1730
return (
1831
<StackedNotification
@@ -22,7 +35,8 @@ const NotificationStack = props => {
2235
action={notification.action || props.action}
2336
dismissAfter={isLast ? dismissAfter : dismissAfter + (index * 1000)}
2437
onDismiss={props.onDismiss.bind(this, notification)}
25-
index={index}
38+
activeBarStyle={activeBarStyle}
39+
barStyle={barStyle}
2640
/>
2741
);
2842
})}
@@ -31,12 +45,16 @@ const NotificationStack = props => {
3145
};
3246

3347
NotificationStack.propTypes = {
48+
activeBarStyleFactory: PropTypes.func,
49+
barStyleFactory: PropTypes.func,
3450
notifications: PropTypes.array.isRequired,
3551
onDismiss: PropTypes.func.isRequired
3652
};
3753

3854
NotificationStack.defaultProps = {
39-
dismissAfter: 1000
55+
dismissAfter: 1000,
56+
activeBarStyleFactory: defaultStyleFactory,
57+
barStyleFactory: defaultStyleFactory
4058
}
4159

4260
export default NotificationStack;

src/stackedNotification.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,11 @@ class StackedNotification extends Component {
2626
}
2727

2828
render() {
29-
const bottomPosition = `${2 + this.props.index * 4}rem`;
30-
3129
return (
3230
<Notification
3331
{...this.props}
3432
onDismiss={() => setTimeout(this.props.onDismiss, 300)}
3533
isActive={this.state.isActive}
36-
barStyle={Object.assign({}, {
37-
bottom: bottomPosition
38-
}, this.props.barStyle)}
39-
activeBarStyle={Object.assign({}, {
40-
bottom: bottomPosition
41-
}, this.props.activeBarStyle)}
4234
/>
4335
);
4436
}

test/notificationStack.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,72 @@ describe('<NotificationStack />', () => {
6767

6868
expect(handleDismiss.calledOnce).to.equal(false);
6969
});
70+
71+
it('barStyleFactory should set correct style on notification', () => {
72+
const styleFactory = (index, style) => Object.assign(
73+
{},
74+
style,
75+
{ bottom: `${index}px` }
76+
);
77+
const stack = mount(
78+
<NotificationStack
79+
notifications={[mockNotification]}
80+
barStyleFactory={styleFactory}
81+
onDismiss={() => {}}
82+
/>
83+
);
84+
const notification = stack.find(Notification);
85+
expect(notification.prop('barStyle').bottom).to.equal('0px');
86+
});
87+
88+
it('barStyleFactory should respect notification barStyle', () => {
89+
const styleFactory = (index, style) => Object.assign(
90+
{},
91+
style,
92+
{ bottom: `${index}px` }
93+
);
94+
const stack = mount(
95+
<NotificationStack
96+
notifications={[mockNotification]}
97+
barStyleFactory={styleFactory}
98+
onDismiss={() => {}}
99+
/>
100+
);
101+
const notification = stack.find(Notification);
102+
expect(notification.prop('barStyle').background).to.equal('rgb(2, 2, 2)');
103+
});
104+
105+
it('activeBarStyleFactory should set correct style on notification', () => {
106+
const styleFactory = (index, style) => Object.assign(
107+
{},
108+
style,
109+
{ bottom: `${index + 2}px` }
110+
);
111+
const stack = mount(
112+
<NotificationStack
113+
notifications={[mockNotification]}
114+
activeBarStyleFactory={styleFactory}
115+
onDismiss={() => {}}
116+
/>
117+
);
118+
const notification = stack.find(Notification);
119+
expect(notification.prop('activeBarStyle').bottom).to.equal('2px');
120+
});
121+
122+
it('activeBarStyleFactory should respect notification actionBarStyle', () => {
123+
const styleFactory = (index, style) => Object.assign(
124+
{},
125+
style,
126+
{ bottom: `${index}px` }
127+
);
128+
const stack = mount(
129+
<NotificationStack
130+
notifications={[mockNotification]}
131+
activeBarStyleFactory={styleFactory}
132+
onDismiss={() => {}}
133+
/>
134+
);
135+
const notification = stack.find(Notification);
136+
expect(notification.prop('activeBarStyle').left).to.equal('4rem');
137+
})
70138
});

0 commit comments

Comments
 (0)