Skip to content

Commit

Permalink
Allow "onClose" and "onExited" callbacks on the SnackbarProvider and …
Browse files Browse the repository at this point in the history
…on single snacks
  • Loading branch information
Robbie op de Weegh committed Nov 5, 2018
1 parent 95047df commit a53a91d
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/SnackbarItem/SnackbarItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import {
class SnackbarItem extends Component {
handleClose = key => (event, reason) => {
const { onClose } = this.props;
if (reason === 'clickaway') return;
onClose(key);

onClose(event, reason, key);
};

render() {
Expand Down
47 changes: 36 additions & 11 deletions src/SnackbarProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,24 +91,37 @@ class SnackbarProvider extends Component {

/**
* Hide a snackbar after its timeout.
* @param {number} key - id of the snackbar we want to hide
*/
handleCloseSnack = (key) => {
this.setState(({ snacks }) => ({
snacks: [
...snacks.map(item => (item.key === key ? { ...item, open: false } : { ...item })),
],
}));
handleCloseSnack = snackOnClose => (event, reason, key) => {
const { onClose } = this.props;

if (reason !== 'clickaway') {
this.setState(({ snacks }) => ({
snacks: [
...snacks
.map(item => (item.key === key ? { ...item, open: false } : { ...item })),
],
}));
}

if (snackOnClose) {
snackOnClose(event, reason, key);
}

if (onClose) {
onClose(event, reason, key);
}
};

/**
* When we set open attribute of a snackbar to false (i.e. after we hide a snackbar),
* it leaves the screen and immediately after leaving animation is done, this method
* gets called. We remove the hidden snackbar from state and then display notifications
* waiting in the queue (if any).
* @param {number} key - id of the snackbar we want to remove
*/
handleExitedSnack = (key) => {
handleExitedSnack = snackOnExited => (key) => {
const { onExited } = this.props;

const enterDelay = TRANSITION_DELAY + TRANSITION_DOWN_DURATION + 40;
this.setState(
({ snacks }) => ({
Expand All @@ -118,6 +131,14 @@ class SnackbarProvider extends Component {
}),
() => setTimeout(this.handleDisplaySnack, enterDelay),
);

if (snackOnExited) {
snackOnExited(key);
}

if (onExited) {
onExited(key);
}
};

render() {
Expand All @@ -135,8 +156,8 @@ class SnackbarProvider extends Component {
key={snack.key}
level={index}
snack={snack}
onClose={this.handleCloseSnack}
onExited={this.handleExitedSnack}
onClose={this.handleCloseSnack(snack.onClose)}
onExited={this.handleExitedSnack(snack.onExited)}
/>
))}
</Fragment>
Expand All @@ -153,10 +174,14 @@ SnackbarProvider.propTypes = {
* on top of one another
*/
maxSnack: PropTypes.number,
onClose: PropTypes.func,
onExited: PropTypes.func,
};

SnackbarProvider.defaultProps = {
maxSnack: 3,
onClose: null,
onExited: null,
};

export default SnackbarProvider;

0 comments on commit a53a91d

Please sign in to comment.