You can check a quick demo here.
npm install --save react-simple-snackbar
or
yarn add react-simple-snackbar
First, you need to wrap your application into a SnackbarProvider
:
// App.js
import React from 'react'
import SnackbarProvider from 'react-simple-snackbar'
import SomeChildComponent from './SomeChildComponent'
export default function App() {
return (
<SnackbarProvider>
<SomeChildComponent />
</SnackbarProvider>
)
}
Then you can use both options on any descendant component:
// SomeChildComponent.js
import React from 'react'
import { useSnackbar } from 'react-simple-snackbar'
export default function SomeChildComponent() {
const [openSnackbar, closeSnackbar] = useSnackbar()
return (
<div>
<button onClick={() => openSnackbar('This is the content of the Snackbar.')}>
Click me to open the Snackbar!
</button>
<button onClick={closeSnackbar}>
Click me to close the Snackbar programmatically.
</button>
</div>
)
}
// SomeChildComponent.js
import React from 'react'
import { withSnackbar } from 'react-simple-snackbar'
class SomeChildComponent extends React.Component {
render() {
const { openSnackbar, closeSnackbar } = this.props
return (
<div>
<button onClick={() => openSnackbar('This is the content of the Snackbar.')}>
Click me to open the Snackbar!
</button>
<button onClick={closeSnackbar}>
Click me to close the Snackbar programmatically.
</button>
</div>
)
}
}
export default withSnackbar(SomeChildComponent)
These methods are are returned from useSnackbar()
hook in array destructuring syntax:
const [openSnackbar, closeSnackbar] = useSnackbar()
// You can also give different names as you wish
const [open, close] = useSnackbar()
Or added as additional props on components wrapped in withSnackbar()
:
const { openSnackbar, closeSnackbar } = this.props
-
node
: the node you want to show into the Snackbar. It can be just"Some string like showed on Basic Usage"
, or<p>Some element you would <strong>like</strong> to show</p>
. -
duration
: a number in milliseconds to set the duration of the Snackbar. The default value is5000
.
- This method is used if you want to close the Snackbar programmatically. It doesn't receive any params.
You can pass an options object to customize your Snackbar. This object can be passed either in useSnackbar([options])
or as second argument of withSnackbar(Component [, options])
. It accepts three options:
-
position
: a custom position for your Snackbar. The default value isbottom-center
, and the possible values aretop-left
,top-center
,top-right
,bottom-left
,bottom-center
andbottom-right
. -
style
: a style object withcamelCased
properties and string values. These styles are applied to the Snackbar itself. -
closeStyle
: same as above, but the styles are applied to the close button. You can use font properties to style theX
icon.
For example:
const options = {
position: 'bottom-right',
style: {
backgroundColor: 'midnightblue',
border: '2px solid lightgreen',
color: 'lightblue',
fontFamily: 'Menlo, monospace',
fontSize: '20px',
textAlign: 'center',
},
closeStyle: {
color: 'lightcoral',
fontSize: '16px',
},
}
// Usage with hooks
useSnackbar(options)
// Usage with HoC
withSnackbar(Component, options)
The snackbar itself is already tested and you don't have to worry about it.
To test components that use Snackbar functionalities, there are some approaches as described bellow. This examples makes use of Jest and Enzyme for testing, but you can use whatever you want.
You can mock the implementation of useSnackbar
to return an array containing openSnackbar
and closeSnackbar
as mocked functions:
// Component.test.js
import React from 'react'
import { shallow } from 'enzyme'
import * as Snackbar from 'react-simple-snackbar'
import Component from './Component'
// Mocks the open and close functions
const openSnackbarMock = jest.fn()
const closeSnackbarMock = jest.fn()
jest.spyOn(Snackbar, 'useSnackbar').mockImplementation(() => [openSnackbarMock, closeSnackbarMock])
it('can test the openSnackbar and closeSnackbar functions', () => {
const wrapper = shallow(<Component />)
// Simulates click on some buttons that opens and closes the Snackbar
wrapper.find('button.open').simulate('click')
wrapper.find('button.close').simulate('click')
// Some examples of how you can test the mocks
expect(openSnackbarMock).toHaveBeenCalled()
expect(openSnackbarMock).toHaveBeenCalledTimes(1)
expect(openSnackbarMock).toHaveBeenCalledWith('This is the text of the Snackbar.')
expect(closeSnackbarMock).toHaveBeenCalled()
expect(closeSnackbarMock).toHaveBeenCalledTimes(1)
})
To make it easier to test and not make use of SnackbarProvider
, you can export your component in isolation as a named export, and as a default export wrapped in withSnackbar()
:
// Component.js
// (...)
// * Here goes all the component's code *
// (...)
// Named export for testing, and default export for using
export { Component }
export default withSnackbar(Component)
So you can get the component as a named import, then mock the openSnackbar
and closeSnackbar
functions as common props if you want:
// Component.test.js
import React from 'react'
import { shallow } from 'enzyme'
import { Component } from './Component'
it('can test the openSnackbar and closeSnackbar functions', () => {
const openSnackbarMock = jest.fn()
const closeSnackbarMock = jest.fn()
const wrapper = shallow(
<Component openSnackbar={openSnackbarMock} closeSnackbar={closeSnackbarMock} />
)
// Simulates click on some buttons that opens and closes the Snackbar
wrapper.find('button.open').simulate('click')
wrapper.find('button.close').simulate('click')
// Some examples of how you can test the mocks
expect(openSnackbarMock).toHaveBeenCalled()
expect(openSnackbarMock).toHaveBeenCalledTimes(1)
expect(openSnackbarMock).toHaveBeenCalledWith('This is the text of the Snackbar.')
expect(closeSnackbarMock).toHaveBeenCalled()
expect(closeSnackbarMock).toHaveBeenCalledTimes(1)
})
See CONTRIBUTING for more information on how to get started.
React Simple Snackbar is open source software licensed as MIT.