diff --git a/src/Form/FormCheckbox.jsx b/src/Form/FormCheckbox.jsx index 02f44b5ebe..9a9b736b89 100644 --- a/src/Form/FormCheckbox.jsx +++ b/src/Form/FormCheckbox.jsx @@ -8,13 +8,19 @@ import FormControlFeedback from './FormControlFeedback'; const CheckboxControl = React.forwardRef( ({ isIndeterminate, ...props }, ref) => { + const { getCheckboxControlProps, hasCheckboxSetProvider } = useCheckboxSetContext(); const defaultRef = React.useRef(); const resolvedRef = ref || defaultRef; const { getControlProps } = useFormGroupContext(); - const checkboxProps = getControlProps({ + let checkboxProps = getControlProps({ ...props, className: classNames('pgn__form-checkbox-input', props.className), }); + + if (hasCheckboxSetProvider) { + checkboxProps = getCheckboxControlProps(checkboxProps); + } + React.useEffect(() => { // this if(resolvedRef.current) prevents console errors in testing if (resolvedRef.current) { diff --git a/src/Form/FormRadio.jsx b/src/Form/FormRadio.jsx index 1a14cefb63..9840f6ab53 100644 --- a/src/Form/FormRadio.jsx +++ b/src/Form/FormRadio.jsx @@ -8,10 +8,16 @@ import FormControlFeedback from './FormControlFeedback'; const RadioControl = React.forwardRef((props, ref) => { const { getControlProps } = useFormGroupContext(); - const radioProps = getControlProps({ + const { getRadioControlProps, hasRadioSetProvider } = useRadioSetContext(); + let radioProps = getControlProps({ ...props, className: classNames('pgn__form-radio-input', props.className), }); + + if (hasRadioSetProvider) { + radioProps = getRadioControlProps(radioProps); + } + return ( ); @@ -95,4 +101,5 @@ FormRadio.defaultProps = { isValid: false, }; +export { RadioControl }; export default FormRadio; diff --git a/src/Form/FormRadioSetContext.jsx b/src/Form/FormRadioSetContext.jsx index a177e3feac..9611fd5ae7 100644 --- a/src/Form/FormRadioSetContext.jsx +++ b/src/Form/FormRadioSetContext.jsx @@ -6,6 +6,7 @@ const identityFn = props => props; const FormRadioSetContext = React.createContext({ getRadioControlProps: identityFn, + hasRadioSetProvider: false, }); const useRadioSetContext = () => useContext(FormRadioSetContext); @@ -40,6 +41,7 @@ function FormRadioSetContextProvider({ onBlur, onFocus, onChange, + hasRadioSetProvider: true, }; return ( diff --git a/src/Form/form-radio.mdx b/src/Form/form-radio.mdx index 57fb7245b3..03ca2625fc 100644 --- a/src/Form/form-radio.mdx +++ b/src/Form/form-radio.mdx @@ -43,6 +43,22 @@ underlying `input` node. See MDN for documentation on available } ``` +## Unlabeled Control + +```jsx live +() => { + const [value, setValue] = useState('green'); + const handleChange = e => setValue(e.target.value); + + return ( + + + + + ) +} +``` + ## Uncontrolled Usage ```jsx live diff --git a/src/Form/index.jsx b/src/Form/index.jsx index 9eaf703130..42cd662ff4 100644 --- a/src/Form/index.jsx +++ b/src/Form/index.jsx @@ -5,7 +5,7 @@ import FormGroup from './FormGroup'; import FormControlFeedback from './FormControlFeedback'; import FormText from './FormText'; import FormControlDecoratorGroup from './FormControlDecoratorGroup'; -import FormRadio from './FormRadio'; +import FormRadio, { RadioControl } from './FormRadio'; import FormRadioSet from './FormRadioSet'; import FormRadioSetContext from './FormRadioSetContext'; import FormAutosuggest from './FormAutosuggest'; @@ -48,6 +48,7 @@ export { FormControlFeedback, FormText, CheckboxControl, + RadioControl, SwitchControl, FormSwitchSet, useCheckboxSetValues, diff --git a/src/SelectableBox/tests/SelectableBox.test.jsx b/src/SelectableBox/tests/SelectableBox.test.jsx index 3731747cbc..66a6fb3a44 100644 --- a/src/SelectableBox/tests/SelectableBox.test.jsx +++ b/src/SelectableBox/tests/SelectableBox.test.jsx @@ -3,7 +3,7 @@ import { mount } from 'enzyme'; import renderer from 'react-test-renderer'; import SelectableBox from '..'; -import { Form } from '../..'; +import { RadioControl, CheckboxControl } from '../../Form'; const checkboxType = 'checkbox'; const checkboxText = 'SelectableCheckbox'; @@ -29,11 +29,11 @@ describe('', () => { }); it('correct render when type prop is changed', () => { const boxWrapper = mount(); - expect(boxWrapper.find(Form.Radio).length).toBeGreaterThan(0); + expect(boxWrapper.find(RadioControl).length).toBeGreaterThan(0); boxWrapper.setProps({ type: 'radio' }); - expect(boxWrapper.find(Form.Radio).length).toBeGreaterThan(0); + expect(boxWrapper.find(RadioControl).length).toBeGreaterThan(0); boxWrapper.setProps({ type: 'checkbox' }); - expect(boxWrapper.find(Form.Checkbox).length).toBeGreaterThan(0); + expect(boxWrapper.find(CheckboxControl).length).toBeGreaterThan(0); }); it('renders with radio input type if neither checkbox nor radio is passed', () => { // Mock the `console.error` is intentional because an invalid `type` prop diff --git a/src/SelectableBox/tests/__snapshots__/SelectableBox.test.jsx.snap b/src/SelectableBox/tests/__snapshots__/SelectableBox.test.jsx.snap index b43cf81f25..96676cabf5 100644 --- a/src/SelectableBox/tests/__snapshots__/SelectableBox.test.jsx.snap +++ b/src/SelectableBox/tests/__snapshots__/SelectableBox.test.jsx.snap @@ -9,25 +9,14 @@ exports[` correct rendering renders without props 1`] = ` role="button" tabIndex={0} > -
- -
-
-
+ SelectableBox `; diff --git a/src/SelectableBox/tests/__snapshots__/SelectableBoxSet.test.jsx.snap b/src/SelectableBox/tests/__snapshots__/SelectableBoxSet.test.jsx.snap index 61d7de481c..f464052336 100644 --- a/src/SelectableBox/tests/__snapshots__/SelectableBoxSet.test.jsx.snap +++ b/src/SelectableBox/tests/__snapshots__/SelectableBoxSet.test.jsx.snap @@ -13,27 +13,16 @@ exports[` correct rendering renders without props 1`] = ` role="button" tabIndex={0} > -
- -
-
-
+ SelectableRadio1
correct rendering renders without props 1`] = ` role="button" tabIndex={0} > -
- -
-
-
+ SelectableRadio2
correct rendering renders without props 1`] = ` role="button" tabIndex={0} > -
- -
-
-
+ SelectableRadio3
diff --git a/src/SelectableBox/tests/utils.test.js b/src/SelectableBox/tests/utils.test.js index 5ee2277e81..c47f3d8b8b 100644 --- a/src/SelectableBox/tests/utils.test.js +++ b/src/SelectableBox/tests/utils.test.js @@ -1,12 +1,12 @@ -import { Form } from '../..'; +import Form, { CheckboxControl, RadioControl } from '../../Form'; import { getInputType } from '../utils'; describe('utils', () => { it('getInputType returns correct type', () => { - expect(getInputType('SelectableBox', undefined)).toEqual(Form.Radio); - expect(getInputType('SelectableBox', 'wrongtype')).toEqual(Form.Radio); - expect(getInputType('SelectableBox', 'radio')).toEqual(Form.Radio); - expect(getInputType('SelectableBox', 'checkbox')).toEqual(Form.Checkbox); + expect(getInputType('SelectableBox', undefined)).toEqual(RadioControl); + expect(getInputType('SelectableBox', 'wrongtype')).toEqual(RadioControl); + expect(getInputType('SelectableBox', 'radio')).toEqual(RadioControl); + expect(getInputType('SelectableBox', 'checkbox')).toEqual(CheckboxControl); expect(getInputType('SelectableBoxSet', undefined)).toEqual(Form.RadioSet); expect(getInputType('SelectableBoxSet', 'wrongtype')).toEqual(Form.RadioSet); expect(getInputType('SelectableBoxSet', 'radio')).toEqual(Form.RadioSet); diff --git a/src/SelectableBox/utils.js b/src/SelectableBox/utils.js index c296ae1fa1..33ce23b766 100644 --- a/src/SelectableBox/utils.js +++ b/src/SelectableBox/utils.js @@ -1,15 +1,15 @@ -import Form from '../Form'; +import Form, { CheckboxControl, RadioControl } from '../Form'; // eslint-disable-next-line import/prefer-default-export,consistent-return export const getInputType = (component, type) => { if (component === 'SelectableBox') { switch (type) { case 'radio': - return Form.Radio; + return RadioControl; case 'checkbox': - return Form.Checkbox; + return CheckboxControl; default: - return Form.Radio; + return RadioControl; } } else if (component === 'SelectableBoxSet') { switch (type) { diff --git a/src/index.js b/src/index.js index a87436f55f..f41436a91f 100644 --- a/src/index.js +++ b/src/index.js @@ -39,6 +39,7 @@ export { default as Fade } from './Fade'; export { default as Fieldset } from './Fieldset'; export { default as Form, + RadioControl, CheckboxControl, SwitchControl, FormSwitchSet,