diff --git a/src/components/CheckboxWithLabel.js b/src/components/CheckboxWithLabel.js index f494895af1027..0b355d05fa218 100644 --- a/src/components/CheckboxWithLabel.js +++ b/src/components/CheckboxWithLabel.js @@ -10,13 +10,10 @@ import * as FormUtils from '../libs/FormUtils'; const propTypes = { /** Whether the checkbox is checked */ - isChecked: PropTypes.bool.isRequired, + isChecked: PropTypes.bool, /** Called when the checkbox or label is pressed */ - onPress: PropTypes.func.isRequired, - - /** Called when the checkbox or label is pressed */ - onChange: PropTypes.func, + onInputChange: PropTypes.func.isRequired, /** Container styles */ style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), @@ -33,6 +30,12 @@ const propTypes = { /** Indicates that the input is being used with the Form component */ isFormInput: PropTypes.bool, + /** The default value for the checkbox */ + defaultValue: PropTypes.bool, + + /** React ref being forwarded to the Checkbox input */ + forwardedRef: PropTypes.func, + /** * The ID used to uniquely identify the input * @@ -46,7 +49,6 @@ const propTypes = { }; const defaultProps = { - onChange: () => {}, isFormInput: false, inputID: undefined, style: [], @@ -54,16 +56,22 @@ const defaultProps = { LabelComponent: undefined, errorText: '', shouldSaveDraft: false, + isChecked: false, + defaultValue: false, + forwardedRef: () => {}, }; -const CheckboxWithLabel = React.forwardRef((props, ref) => { +const CheckboxWithLabel = (props) => { const LabelComponent = props.LabelComponent; const defaultStyles = [styles.flexRow, styles.alignItemsCenter]; const wrapperStyles = _.isArray(props.style) ? [...defaultStyles, ...props.style] : [...defaultStyles, props.style]; + // We keep track of the checkbox "state" in a local variable so that this component has an uncontrolled input interface + let isChecked = props.defaultValue ? props.defaultValue : props.isChecked; + function toggleCheckbox() { - props.onPress(!props.isChecked); - props.onChange(!props.isChecked); + props.onInputChange(!isChecked); + isChecked = !isChecked; } if (!props.label && !LabelComponent) { @@ -73,11 +81,11 @@ const CheckboxWithLabel = React.forwardRef((props, ref) => { <> { ); -}); +}; CheckboxWithLabel.propTypes = propTypes; CheckboxWithLabel.defaultProps = defaultProps; CheckboxWithLabel.displayName = 'CheckboxWithLabel'; -export default CheckboxWithLabel; +export default React.forwardRef((props, ref) => ( + // eslint-disable-next-line react/jsx-props-no-spreading + +)); diff --git a/src/pages/EnablePayments/TermsStep.js b/src/pages/EnablePayments/TermsStep.js index 823c617396492..c1da54aa6aec3 100644 --- a/src/pages/EnablePayments/TermsStep.js +++ b/src/pages/EnablePayments/TermsStep.js @@ -76,7 +76,7 @@ class TermsStep extends React.Component { ( {`${this.props.translate('termsStep.haveReadAndAgree')}`} @@ -88,7 +88,7 @@ class TermsStep extends React.Component { /> ( <> diff --git a/src/pages/ReimbursementAccount/ACHContractStep.js b/src/pages/ReimbursementAccount/ACHContractStep.js index 30b99f2f9f055..20c9d5f663ec5 100644 --- a/src/pages/ReimbursementAccount/ACHContractStep.js +++ b/src/pages/ReimbursementAccount/ACHContractStep.js @@ -185,7 +185,7 @@ class ACHContractStep extends React.Component { this.toggleCheckbox('ownsMoreThan25Percent')} + onInputChange={() => this.toggleCheckbox('ownsMoreThan25Percent')} LabelComponent={() => ( {this.props.translate('beneficialOwnersStep.iOwnMoreThan25Percent')} @@ -196,7 +196,7 @@ class ACHContractStep extends React.Component { { + onInputChange={() => { this.setState((prevState) => { const hasOtherBeneficialOwners = !prevState.hasOtherBeneficialOwners; const newState = { @@ -259,7 +259,7 @@ class ACHContractStep extends React.Component { this.toggleCheckbox('acceptTermsAndConditions')} + onInputChange={() => this.toggleCheckbox('acceptTermsAndConditions')} LabelComponent={() => ( {this.props.translate('common.iAcceptThe')} @@ -274,7 +274,7 @@ class ACHContractStep extends React.Component { this.toggleCheckbox('certifyTrueInformation')} + onInputChange={() => this.toggleCheckbox('certifyTrueInformation')} LabelComponent={() => ( {this.props.translate('beneficialOwnersStep.certifyTrueAndAccurate')} )} diff --git a/src/pages/ReimbursementAccount/BankAccountStep.js b/src/pages/ReimbursementAccount/BankAccountStep.js index a3dff5c46afff..0f57fba0cf57c 100644 --- a/src/pages/ReimbursementAccount/BankAccountStep.js +++ b/src/pages/ReimbursementAccount/BankAccountStep.js @@ -302,7 +302,7 @@ class BankAccountStep extends React.Component { ( diff --git a/src/pages/ReimbursementAccount/CompanyStep.js b/src/pages/ReimbursementAccount/CompanyStep.js index 6a95f2e56b447..384a7bfeba051 100644 --- a/src/pages/ReimbursementAccount/CompanyStep.js +++ b/src/pages/ReimbursementAccount/CompanyStep.js @@ -294,7 +294,7 @@ class CompanyStep extends React.Component { { + onInputChange={() => { this.setState((prevState) => { const newState = {hasNoConnectionToCannabis: !prevState.hasNoConnectionToCannabis}; BankAccounts.updateReimbursementAccountDraft(newState); diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 04237bda2c21d..1e2506ac3f0a9 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -211,7 +211,7 @@ class RequestorStep extends React.Component { /> { + onInputChange={() => { this.setState((prevState) => { const newState = {isControllingOfficer: !prevState.isControllingOfficer}; BankAccounts.updateReimbursementAccountDraft(newState); diff --git a/src/pages/settings/Payments/AddDebitCardPage.js b/src/pages/settings/Payments/AddDebitCardPage.js index 84b45ed49170b..e6a8406c1cea1 100644 --- a/src/pages/settings/Payments/AddDebitCardPage.js +++ b/src/pages/settings/Payments/AddDebitCardPage.js @@ -318,7 +318,7 @@ class DebitCardPage extends Component { { + onInputChange={() => { this.setState(prevState => ({ acceptedTerms: !prevState.acceptedTerms, errors: { diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js index 333412eac91dd..ad58f15e3a6f6 100755 --- a/src/pages/settings/Profile/ProfilePage.js +++ b/src/pages/settings/Profile/ProfilePage.js @@ -298,7 +298,7 @@ class ProfilePage extends Component { diff --git a/src/stories/Form.stories.js b/src/stories/Form.stories.js index e0e551bb17c97..262a9f3a1c90a 100644 --- a/src/stories/Form.stories.js +++ b/src/stories/Form.stories.js @@ -26,8 +26,6 @@ const story = { }; const Template = (args) => { - const [isChecked, setIsChecked] = useState(args.draftValues.checkbox); - // Form consumes data from Onyx, so we initialize Onyx with the necessary data here FormActions.setIsSubmitting(args.formID, args.formState.isSubmitting); FormActions.setServerErrorMessage(args.formID, args.formState.serverErrorMessage); @@ -101,10 +99,7 @@ const Template = (args) => { /> { setIsChecked(prev => !prev); }} isFormInput shouldSaveDraft LabelComponent={() => (