App: [HOLD for payment 2022-05-24] [$1000] [HOLD for payment after regression testing] Refactor Picker to be compatible with Form

With the implementation of our new Form component we need to refactor Picker to be Form compatible. Here are the changes that need to be made:

  1. An optional isFormInput prop.
  2. If isFormInput is true, require a inputID prop. Use getInputIDPropTypes to enforce this propType rule.
  3. Add an optional shouldSaveDraft prop. Defaults to false.
  4. Make the value prop optional.
  5. In the input’s onBlur method, call props.onBlur().
  6. In the input’s onChange method (or equivalent e.g. onTextChange, etc), call props.onChange().
  7. Remove the hasError prop.
  8. Add an optional errorText prop. Defaults to an empty string.
  9. Update the error message to display if errorText is truthy.
  10. Update the inline error display style so it is left aligned with the label and input value. See example image for TextInput: Screen Shot 2022-02-02 at 10 37 38 AM
  11. Make sure that props.ref is attached to the appropriate DOM node. This could involve forwarding the ref to a child component. This is important so we can call ref.focus().
  12. Add the input to the test Form stories and make sure that it works. You can check this by running npm run storybook and testing the component in the example form.
  13. Remove any unused code.

There’s an example of a refactor to TextInput in this PR.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 93 (82 by maintainers)

Most upvoted comments

Just noting for the record that @parasharrajat needs a reporting bonus for reporting the regression here. The regression issue is here, but we decided to use this issue to manage everything to avoid confusion.

cc: @laurenreidexpensify @stitesExpensify

I found a solution to blur regression

We need to fire onClose along with onBlur.

class BasePicker extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            selectedValue: this.props.defaultValue,
        };

        this.updateSelectedValueAndExecuteOnChange = this.updateSelectedValueAndExecuteOnChange.bind(this);
++   this.executeOnCloseAndOnBlur = this.executeOnCloseAndOnBlur.bind(this);
    }

    updateSelectedValueAndExecuteOnChange(value) {
        this.props.onInputChange(value);
        this.setState({selectedValue: value});
    }

++    executeOnCloseAndOnBlur() {
++       this.props.onClose();
++
++       if (this.props.onBlur) {
++            this.props.onBlur();
++        }
++    }

    render() {
        const hasError = !_.isEmpty(this.props.errorText);
        return (
            <RNPickerSelect
                onValueChange={this.updateSelectedValueAndExecuteOnChange}
                items={this.props.items}
                style={this.props.size === 'normal' ? basePickerStyles(this.props.disabled, hasError, this.props.focused) : styles.pickerSmall}
                useNativeAndroidPickerStyle={false}
                placeholder={this.props.placeholder}
                value={this.props.value || this.state.selectedValue}
                Icon={() => this.props.icon(this.props.size)}
                disabled={this.props.disabled}
                fixAndroidTouchableBug
                onOpen={this.props.onOpen}
                onClose={this.props.onClose}
                pickerProps={{
                    onFocus: this.props.onOpen,
--                 onBlur: this.props.onBlur,
++               onBlur: this.executeOnCloseAndOnBlur,
                    ref: this.props.innerRef,
                }}
            />
        );
    }
}

No, that has been solved and the PR is currently in review!

@parasharrajat all done - sorry about that!

@LucioChavezFuentes payment has been issued 👍🏽

Ah, yes! That title doesn’t update automatically. I’ve updated this to reflect the correct amount.

There was a regression on the PR and a temporary fix was deployed. We are still looking for a better permanent fix. Not sure if this changes the payment schedule or not.

Today I am available but I will be out for a week starting tomorrow. I apologize for the incoveninece this may arise.

Update, I only need to test my Picker on IOS and Mac, I am currently creating a Mac mini M1 instance on Scaleway.

Guys, I don’t think I can deliver a Pull Request on Friday but until next week. I apologize for the inconvenience.

About scrolling on focus( ) I think it depends on tags or components you are trying to focus. On Web, Picker renders a <select> and I confirm executing focus ( ) on it does make a scroll. Meanwhile I tried to focus on a <div> and it doesn’t make scroll.

@rushatgabhane hmm I remember testing it and having the input scroll into view on all devices. We are planning on using focus to simplify the implementation of scrolling into view.

Yes, it is! But it requires that the ref expose a focus() method.

I decided to check Picker and modify a little its forwardRef implementation inside mode_modules, and I finally got the DOM instance with focus( ) passing ref to pickerProps, it still does not show the picker’s dropdown list when I click ‘fix errors’ but it proves Picker does not forward ref, at least at the version we are using.

Original code inside node_modules/@react-native-picker/picker/js/Picker.web.js

image

Modified code inside node_modules/@react-native-picker/picker/js/Picker.web.js

image

Passing ref to pickerProps:

image

DOM ref available:

image

**handleOpen executes when click ‘fix the errors’, which is passed on onFocus pickerProps **

image

What do you gus think?

I had an issue rendering Picker component inside Form.stories.js. But I fix it by installing @storybook/addon-react-native-web as devDependency and add it on .storybook\main.js on addons array. The problem was related to No loader found for this type of file and it is documented in storybook, more info: https://github.com/storybookjs/addon-react-native-web/blob/main/README.md#common-issues. Is it OK to install this devDependecy?

packaje.json image

.storybook\main.js image

Thank you! I submitted my proposal on Upwork. I plan to finish the issue on Wednesday, 9th February.