/
RadioGroup.js
111 lines (99 loc) · 3 KB
/
RadioGroup.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
import React from 'react';
import PropTypes from 'prop-types';
import FormGroup from '../FormGroup';
import useForkRef from '../utils/useForkRef';
import RadioGroupContext from './RadioGroupContext';
const RadioGroup = React.forwardRef(function RadioGroup(props, ref) {
const { actions, children, name, value: valueProp, onChange, ...other } = props;
const rootRef = React.useRef(null);
const { current: isControlled } = React.useRef(valueProp != null);
const [valueState, setValue] = React.useState(props.defaultValue);
const value = isControlled ? valueProp : valueState;
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line react-hooks/rules-of-hooks
React.useEffect(() => {
if (isControlled !== (valueProp != null)) {
console.error(
[
`Material-UI: A component is changing ${
isControlled ? 'a ' : 'an un'
}controlled RadioGroup to be ${isControlled ? 'un' : ''}controlled.`,
'Elements should not switch from uncontrolled to controlled (or vice versa).',
'Decide between using a controlled or uncontrolled RadioGroup ' +
'element for the lifetime of the component.',
'More info: https://fb.me/react-controlled-components',
].join('\n'),
);
}
}, [valueProp, isControlled]);
}
React.useImperativeHandle(
actions,
() => ({
focus: () => {
let input = rootRef.current.querySelector('input:not(:disabled):checked');
if (!input) {
input = rootRef.current.querySelector('input:not(:disabled)');
}
if (input) {
input.focus();
}
},
}),
[],
);
const handleRef = useForkRef(ref, rootRef);
const handleChange = event => {
if (!isControlled) {
setValue(event.target.value);
}
if (onChange) {
onChange(event, event.target.value);
}
};
return (
<RadioGroupContext.Provider value={{ name, onChange: handleChange, value }}>
<FormGroup role="radiogroup" ref={handleRef} {...other}>
{children}
</FormGroup>
</RadioGroupContext.Provider>
);
});
RadioGroup.propTypes = {
/**
* @ignore
*/
actions: PropTypes.shape({ current: PropTypes.object }),
/**
* The content of the component.
*/
children: PropTypes.node,
/**
* The default `input` element value. Use when the component is not controlled.
*/
defaultValue: PropTypes.any,
/**
* The name used to reference the value of the control.
*/
name: PropTypes.string,
/**
* @ignore
*/
onBlur: PropTypes.func,
/**
* Callback fired when a radio button is selected.
*
* @param {object} event The event source of the callback.
* You can pull out the new value by accessing `event.target.value` (string).
*/
onChange: PropTypes.func,
/**
* @ignore
*/
onKeyDown: PropTypes.func,
/**
* Value of the selected radio button. The DOM API casts this to a string.
*/
value: PropTypes.any,
};
export default RadioGroup;