-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
/
Copy pathToggleButtonGroup.js
143 lines (124 loc) · 3.58 KB
/
ToggleButtonGroup.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { withStyles } from '@material-ui/core/styles';
import hasValue from './hasValue';
import isValueSelected from './isValueSelected';
export const styles = theme => ({
/* Styles applied to the root element. */
root: {
transition: theme.transitions.create('background,box-shadow'),
background: 'transparent',
borderRadius: 2,
overflow: 'hidden',
},
/* Styles applied to the root element if `selected={true}` or `selected="auto" and `value` set. */
selected: {
background: theme.palette.background.paper,
boxShadow: theme.shadows[2],
},
});
class ToggleButtonGroup extends React.Component {
handleChange = buttonValue => {
const { onChange, value } = this.props;
if (!onChange) {
return;
}
const index = value && value.indexOf(buttonValue);
let newValue;
if (value && index >= 0) {
newValue = [...value];
newValue.splice(index, 1);
if (newValue.length === 0) newValue = null;
} else {
newValue = value ? [...value, buttonValue] : [buttonValue];
}
onChange(newValue);
};
handleExclusiveChange = buttonValue => {
const { onChange, value } = this.props;
if (!onChange) {
return;
}
onChange(value === buttonValue ? null : buttonValue);
};
render() {
const {
children: childrenProp,
className: classNameProp,
classes,
exclusive,
onChange,
selected: selectedProp,
value,
...other
} = this.props;
const children = React.Children.map(childrenProp, child => {
if (!React.isValidElement(child)) {
return null;
}
const { selected: buttonSelected, value: buttonValue } = child.props;
const selected =
buttonSelected === undefined ? isValueSelected(buttonValue, value) : buttonSelected;
return React.cloneElement(child, {
selected,
onChange: exclusive ? this.handleExclusiveChange : this.handleChange,
});
});
const groupSelected = selectedProp === 'auto' ? hasValue(value) : selectedProp;
const className = classNames(
classes.root,
{
[classes.selected]: groupSelected,
},
classNameProp,
);
return (
<div className={className} {...other}>
{children}
</div>
);
}
}
ToggleButtonGroup.propTypes = {
/**
* The content of the button.
*/
children: PropTypes.node.isRequired,
/**
* Useful to extend the style applied to components.
*/
classes: PropTypes.object.isRequired,
/**
* @ignore
*/
className: PropTypes.string,
/**
* If `true` only allow one of the child ToggleButton values to be selected.
*/
exclusive: PropTypes.bool,
/**
* Callback fired when the value changes.
*
* @param {object} event The event source of the callback
* @param {object} value of the selected buttons. When `exclusive` is true
* this is a single value; when false an array of selected values.
*/
onChange: PropTypes.func,
/**
* If `true` render the group in a selected state. If `auto` (the default)
* render in a selected state if `value` is not empty.
*/
selected: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['auto'])]),
/**
* The currently selected value within the group or an array of selected
* values when `exclusive` is false.
*/
value: PropTypes.any,
};
ToggleButtonGroup.defaultProps = {
exclusive: false,
selected: 'auto',
value: null,
};
export default withStyles(styles, { name: 'MuiToggleButtonGroup' })(ToggleButtonGroup);