forked from ziad-saab/react-checkbox-group
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreact-checkbox-group.jsx
More file actions
114 lines (97 loc) · 2.93 KB
/
react-checkbox-group.jsx
File metadata and controls
114 lines (97 loc) · 2.93 KB
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
import React, {Component} from 'react';
export class Checkbox extends Component {
static displayName = 'Checkbox';
componentWillMount() {
if (!(this.props && this.props.checkboxGroup)) {
throw new Error('The `Checkbox` component must be used as a child of `CheckboxGroup`.');
}
}
render() {
const {checkboxGroup: {name, checkedValues, onChange}, ...rest} = this.props;
const optional = {};
if (checkedValues) {
optional.checked = (checkedValues.indexOf(this.props.value) >= 0);
}
if (typeof onChange === 'function') {
optional.onChange = onChange.bind(null, this.props.value);
}
return (
<input
{...rest}
type="checkbox"
name={name}
disabled={this.props.disabled}
{...optional}
/>
);
}
}
export class CheckboxGroup extends Component {
static displayName = 'CheckboxGroup';
static defaultProps = {
Component: "div"
};
constructor(props) {
super(props);
this._isControlledComponent = this._isControlledComponent.bind(this);
this._onCheckboxChange = this._onCheckboxChange.bind(this);
this.getValue = this.getValue.bind(this);
this.state = {
value: this.props.value || this.props.defaultValue || []
};
}
componentWillReceiveProps(newProps) {
if (newProps.value) {
this.setState({
value: newProps.value
});
}
}
_prepareBoxes = (children, maxDepth=1, depth=1) => {
if (depth > maxDepth) {
return children;
}
const checkboxGroup = {
name: this.props.name,
checkedValues: this.state.value,
onChange: this._onCheckboxChange
};
return React.Children.map(children, child => {
if (!(child && child.$$typeof)) {
return child;
}
else if (child.type === Checkbox || child.type && child.type.prototype instanceof Checkbox) {
return React.cloneElement(child, {checkboxGroup})
}
else {
return React.cloneElement(child, {}, child.props.children ? React.Children.map(child.props.children, c => this._prepareBoxes(c, maxDepth, depth + 1)) : null)
}
});
};
render() {
const {Component, name, value, onChange, children, checkboxDepth = 1, ...rest} = this.props;
return <Component {...rest}>{this._prepareBoxes(children, checkboxDepth)}</Component>;
}
getValue() {
return this.state.value;
}
_isControlledComponent() {
return Boolean(this.props.value);
}
_onCheckboxChange(checkboxValue, event) {
let newValue;
if (event.target.checked) {
newValue = this.state.value.concat(checkboxValue);
} else {
newValue = this.state.value.filter(v => v !== checkboxValue);
}
if (this._isControlledComponent()) {
this.setState({value: this.props.value});
} else {
this.setState({value: newValue});
}
if (typeof this.props.onChange === 'function') {
this.props.onChange(newValue, event, this.props.name);
}
}
}