Skip to content

Commit

Permalink
[RadioGroup] Random default name (mui#19890)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfernandez-asapp authored and EsoterikStare committed Mar 30, 2020
1 parent d13ad5e commit e43d6e9
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/pages/api/radio-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
|:-----|:-----|:--------|:------------|
| <span class="prop-name">children</span> | <span class="prop-type">node</span> | | The content of the component. |
| <span class="prop-name">defaultValue</span> | <span class="prop-type">any</span> | | The default `input` element value. Use when the component is not controlled. |
| <span class="prop-name">name</span> | <span class="prop-type">string</span> | | The name used to reference the value of the control. |
| <span class="prop-name">name</span> | <span class="prop-type">string</span> | | The name used to reference the value of the control. If you don't provide this prop, it falls back to a randomly generated name. |
| <span class="prop-name">onChange</span> | <span class="prop-type">func</span> | | Callback fired when a radio button is selected.<br><br>**Signature:**<br>`function(event: object) => void`<br>*event:* The event source of the callback. You can pull out the new value by accessing `event.target.value` (string). |
| <span class="prop-name">value</span> | <span class="prop-type">any</span> | | Value of the selected radio button. The DOM API casts this to a string. |

Expand Down
12 changes: 11 additions & 1 deletion packages/material-ui/src/RadioGroup/RadioGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import useControlled from '../utils/useControlled';
import RadioGroupContext from './RadioGroupContext';

const RadioGroup = React.forwardRef(function RadioGroup(props, ref) {
const { actions, children, name, value: valueProp, onChange, ...other } = props;
const { actions, children, name: nameProp, value: valueProp, onChange, ...other } = props;
const rootRef = React.useRef(null);

const [value, setValue] = useControlled({
Expand Down Expand Up @@ -43,6 +43,15 @@ const RadioGroup = React.forwardRef(function RadioGroup(props, ref) {
}
};

const [defaultName, setDefaultName] = React.useState();
const name = nameProp || defaultName;
React.useEffect(() => {
// Fallback to this default name when possible.
// Use the random value for client-side rendering only.
// We can't use it server-side.
setDefaultName(`mui-radiogroup-${Math.round(Math.random() * 1e5)}`);
}, []);

return (
<RadioGroupContext.Provider value={{ name, onChange: handleChange, value }}>
<FormGroup role="radiogroup" ref={handleRef} {...other}>
Expand All @@ -67,6 +76,7 @@ RadioGroup.propTypes = {
defaultValue: PropTypes.any,
/**
* The name used to reference the value of the control.
* If you don't provide this prop, it falls back to a randomly generated name.
*/
name: PropTypes.string,
/**
Expand Down
22 changes: 22 additions & 0 deletions packages/material-ui/src/RadioGroup/RadioGroup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ describe('<RadioGroup />', () => {
assert.strictEqual(findRadio(wrapper, 'one').props().checked, true);
});

it('should have a default name', () => {
const wrapper = mount(
<RadioGroup>
<Radio value="zero" />
<Radio value="one" />
</RadioGroup>,
);

assert.match(findRadio(wrapper, 'zero').props().name, /^mui-radiogroup-[0-9]+/);
assert.match(findRadio(wrapper, 'one').props().name, /^mui-radiogroup-[0-9]+/);
});

describe('imperative focus()', () => {
it('should focus the first non-disabled radio', () => {
const actionsRef = React.createRef();
Expand Down Expand Up @@ -295,6 +307,16 @@ describe('<RadioGroup />', () => {
setProps({ value: 'one' });
expect(radioGroupRef.current).to.have.property('value', 'one');
});

it('should have a default name from the instance', () => {
const radioGroupRef = React.createRef();
const { setProps } = render(<RadioGroupControlled ref={radioGroupRef} />);

expect(radioGroupRef.current.name).to.match(/^mui-radiogroup-[0-9]+/);

setProps({ name: 'anotherGroup' });
expect(radioGroupRef.current).to.have.property('name', 'anotherGroup');
});
});

describe('callbacks', () => {
Expand Down

0 comments on commit e43d6e9

Please sign in to comment.