Skip to content

Commit 74c7a64

Browse files
committed
Merge branch 'snack_bar' into 'master'
Snack bar See merge request code.brahma/react-lite-ui!6
2 parents f418800 + 362566d commit 74c7a64

File tree

7 files changed

+248
-20
lines changed

7 files changed

+248
-20
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
export const defaultCode = `
2+
class SnackDisplay extends React.Component {
3+
constructor(props) {
4+
super(props);
5+
this.state = {
6+
showSnackbar: false,
7+
showTopSnackbar: false,
8+
showIndefiniteSnackbar: false,
9+
}
10+
this.openBottomSnackbar = this.openBottomSnackbar.bind(this);
11+
this.openTopSnackbar = this.openTopSnackbar.bind(this);
12+
this.openIndefiniteSnackbar = this.openIndefiniteSnackbar.bind(this);
13+
this.handleSnackClose = this.handleSnackClose.bind(this);
14+
}
15+
16+
openBottomSnackbar() {
17+
this.setState({
18+
showSnackbar: !this.state.showSnackbar
19+
});
20+
}
21+
22+
openTopSnackbar() {
23+
this.setState({
24+
showTopSnackbar: !this.state.showTopSnackbar
25+
});
26+
}
27+
28+
openIndefiniteSnackbar() {
29+
this.setState({
30+
showIndefiniteSnackbar: !this.state.showIndefiniteSnackbar
31+
});
32+
}
33+
34+
35+
handleSnackClose() {
36+
this.setState({
37+
showSnackbar: false,
38+
showTopSnackbar: false,
39+
});
40+
}
41+
42+
render() {
43+
return (
44+
<div>
45+
<Snackbar
46+
active={this.state.showSnackbar}
47+
onClose={this.handleSnackClose}>
48+
<span>This is a bottom snackbar.</span>
49+
</Snackbar>
50+
<Snackbar
51+
active={this.state.showTopSnackbar}
52+
onClose={this.handleSnackClose}
53+
position='top'>
54+
<span>This is a top snackbar.</span>
55+
</Snackbar>
56+
<Snackbar
57+
active={this.state.showIndefiniteSnackbar}
58+
onClose={this.handleSnackClose}
59+
autoClose={false}>
60+
<span>This is a indefinite snackbar.</span>
61+
</Snackbar>
62+
<div style={{margin: '10px'}}>
63+
<Button type="primary" onClick={this.openBottomSnackbar}>Open Bottom Snackbar</Button>
64+
</div>
65+
<div style={{margin: '10px'}}>
66+
<Button type="primary" onClick={this.openTopSnackbar}>Open Top Snackbar</Button>
67+
</div>
68+
<div style={{margin: '10px'}}>
69+
<Button type="primary" onClick={this.openIndefiniteSnackbar}>{this.state.showIndefiniteSnackbar ? 'Close' : 'Open'} indefinite Snackbar</Button>
70+
</div>
71+
</div>
72+
)
73+
}
74+
}
75+
`

docs/client/components/common/DefaultCode/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ export { defaultCode as CheckboxGroupDefaultCode } from './CheckboxGroup';
55
export { defaultCode as ToggleDefaultCode } from './Toggle';
66
export { defaultCode as RadioButtonGroupDefaultCode } from './RadioButtonGroup';
77
export { defaultCode as TextInputDefaultCode } from './TextInput';
8+
export { defaultCode as SnackbarDefaultCode } from './Snackbar';

docs/client/components/common/componentList.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import ToggleReadme from '../../../../src/toggle/readMe.md';
1111
import RadioButtonGroup from '../../../../src/radioButtonGroup';
1212
import TextInput from '../../../../src/textInput';
1313
import TextInputReadme from '../../../../src/textInput/readMe.md';
14+
import Snackbar from '../../../../src/snackbar';
15+
import SnackbarReadme from '../../../../src/snackbar/readMe.md';
1416

1517
import {
1618
CardDefaultCode,
@@ -20,6 +22,7 @@ import {
2022
ToggleDefaultCode,
2123
RadioButtonGroupDefaultCode,
2224
TextInputDefaultCode,
25+
SnackbarDefaultCode,
2326
} from './DefaultCode';
2427

2528
export const componentList = [
@@ -64,5 +67,11 @@ export const componentList = [
6467
docs: TextInputReadme,
6568
component: TextInput,
6669
defaultCode: TextInputDefaultCode,
70+
},
71+
{
72+
name: 'Snackbar',
73+
docs: SnackbarReadme,
74+
component: Snackbar,
75+
defaultCode: SnackbarDefaultCode,
6776
}
6877
];

src/index.js

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import CheckboxGroup from './checkboxGroup';
77
import Toggle from './toggle';
88
import RadioButtonGroup from './radioButtonGroup';
99
import TextInput from './textInput';
10+
import Snackbar from './snackbar';
1011

1112
export default {
1213
Button,
@@ -15,24 +16,6 @@ export default {
1516
CheckboxGroup,
1617
RadioButtonGroup,
1718
Toggle,
18-
TextInput
19+
TextInput,
20+
Snackbar,
1921
};
20-
21-
// import React from 'react';
22-
// import ReactDOM from 'react-dom';
23-
24-
// import RadioButtonGroup from './radioButtonGroup';
25-
// import theme from './theme.scss';
26-
27-
// const options = [{ label: 'Alpha' }, { label: 'Beta' }, { label: 'Zheta' }]
28-
// const RadioDisplay = () => (
29-
// <div>
30-
// <RadioButtonGroup
31-
// theme={theme}
32-
// options={options}
33-
// inline
34-
// />
35-
// </div>
36-
// );
37-
38-
// ReactDOM.render(<RadioDisplay />, document.getElementById('index'));

src/snackbar/index.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import classnames from 'classnames';
4+
import { themr } from 'react-css-themr';
5+
import defaultTheme from './theme.scss';
6+
7+
class Snackbar extends React.Component {
8+
constructor(props) {
9+
super(props);
10+
this.state = {
11+
active: false,
12+
}
13+
}
14+
15+
componentDidMount() {
16+
if (this.props.active) {
17+
this.showSnackbar();
18+
}
19+
}
20+
21+
componentWillReceiveProps(nextProps) {
22+
if (nextProps.active === this.state.active) {
23+
return;
24+
}
25+
if (nextProps.active) {
26+
this.showSnackbar();
27+
} else {
28+
this.dismissSnackbar();
29+
}
30+
}
31+
32+
scheduleTimeout = (props) => {
33+
const { timeout } = props;
34+
if (this.curTimeout) clearTimeout(this.curTimeout);
35+
this.curTimeout = setTimeout(() => {
36+
this.dismissSnackbar();
37+
this.curTimeout = null;
38+
}, timeout);
39+
}
40+
41+
componentWillUnmount() {
42+
clearTimeout(this.curTimeout);
43+
}
44+
45+
showSnackbar = () => {
46+
if (this.props.autoClose) {
47+
this.scheduleTimeout(this.props);
48+
}
49+
this.setState({
50+
active: true,
51+
});
52+
}
53+
54+
dismissSnackbar = () => {
55+
clearTimeout(this.curTimeout);
56+
this.setState({
57+
active: false,
58+
});
59+
if (this.props.onClose) {
60+
this.props.onClose()
61+
}
62+
}
63+
64+
render() {
65+
const { theme, additionaClasses, position, children } = this.props;
66+
const { active } = this.state;
67+
const classes = classnames(theme.snackbar, additionaClasses)
68+
return (
69+
<div className={classnames(theme.snackbarWrapper, position, active ? 'active' : '')}>
70+
<div className={classes}>
71+
{ children }
72+
</div>
73+
</div>
74+
)
75+
}
76+
}
77+
78+
Snackbar.propTypes = {
79+
additionaClasses: PropTypes.string,
80+
timeout: PropTypes.number,
81+
onClose: PropTypes.func,
82+
autoClose: PropTypes.bool,
83+
position: PropTypes.string,
84+
}
85+
86+
Snackbar.defaultProps = {
87+
additionaClasses: null,
88+
timeout: 2000,
89+
autoClose: true,
90+
position: 'bottom',
91+
};
92+
93+
export default themr('CBSnackbar', defaultTheme)(Snackbar);

src/snackbar/readMe.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## Button
2+
3+
The base Snackbar component.
4+
5+
### Properties
6+
| Name | Type | Default | Description |
7+
|:-----|:-----|:-----|:-----|
8+
| `children` | `Any` | `null` | All children components to be rendered inside the Snackbar |
9+
| `timeout` | `Number` | 2000 | Timeout to auto hide the snackbar |
10+
| `autoClose` | `Boolean` | true | Prop to decide whether the snackbar should close automatically after the given timeout or not |
11+
| `onClose` | `function` | null | The callback function to be called when the snackbar closes |
12+
| `position` | `String` | `bottom` | The position at which the snackbar should be show. The possible values are `top`, `bottom` |
13+
14+
### Theme
15+
16+
| Name | Description|
17+
|:---------|:-----------|
18+
| `snackbar` | Class used for the snackbar element.|
19+
| `snackbarWrapper` | Class used for snackbar wrapper element |
20+
21+
### Usage
22+
23+
```
24+
<div>
25+
<Snackbar
26+
active={this.state.showIndefiniteSnackbar}
27+
onClose={this.handleSnackClose}
28+
autoClose={false}>
29+
<span>This is a indefinite snackbar.</span>
30+
</Snackbar>
31+
</div>
32+
```

src/snackbar/theme.scss

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@import '../globals/theme';
2+
3+
:local(.snackbarWrapper) {
4+
position: fixed;
5+
width: 100%;
6+
right: 0;
7+
&.top {
8+
top: 10%;
9+
&:not(.active) {
10+
transform: translateY(-1000%);
11+
}
12+
13+
&.active {
14+
transform: translateY(0%);
15+
}
16+
}
17+
&.bottom {
18+
bottom: 10%;
19+
&:not(.active) {
20+
transform: translateY(1000%);
21+
}
22+
23+
&.active {
24+
transform: translateY(0%);
25+
}
26+
}
27+
}
28+
29+
:local(.snackbar) {
30+
background: $primary-color;
31+
border-radius: 3px;
32+
padding: 10px;
33+
margin: 0 auto;
34+
width: 40%;
35+
}

0 commit comments

Comments
 (0)