LaunchPadLab / lp-components

Our Components
http://lp-components.herokuapp.com
MIT License
5 stars 1 forks source link

Cannot programmatically focus the textarea input in the Textarea component #470

Closed danparnella closed 3 years ago

danparnella commented 3 years ago

Without using DOM traversal with standard Javascript, I haven't been able to find a way to programmatically focus the textarea input in the Textarea component. My suggestion is to allow for a forwardRef prop on Textarea that would be passed down to the textarea input. That ref could then be used to target the input itself for focusing.

chawes13 commented 3 years ago

I ran into this issue yesterday with our base Input component.

Can we use React.forwardRef? Here's a reference from Styled Components: https://github.com/system-ui/theme-ui/pull/817/files

Ideally this would be applied to all of our inputs, but I'm ok with that being a separate PR to expedite the fix for Artlook

chawes13 commented 3 years ago

That being said, we will probably run into an issue with how redux-forms Field component wraps our components. From the documentation, it looks like their ref forwarding implementation via getRenderedComponent only works if the component is a class component.

I initially thought we might be able to get away with something like the below, but haven't tested it. I did see one SO post that said it wasn't working for them.

<Field
  name="content"
  component={(props) => <Input ref={inputRef} {...props} />}
/>

This approach may have some downsides when it comes to react dev tools and component display names. It's also not very dev friendly. Another workaround could be to also accept a forwardedRef prop (since forwardRef is reserved by redux-form) and pass that into our input. Something like,

export default React.forwardRef(function Input ({ forwardedRef, ...inputProps }, ref) {
  return (
    <input ref={forwardedRef || ref} {...inputProps} />
  )
})
danparnella commented 3 years ago

Yeah, that was originally was my hope (to just export our component with forwardRef), but yes I ran straight into that class restriction ☹️ . Your last suggestion is basically what I ended up doing in my band-aid override, but without the fallback to using the correct forwardRef implementation (and I think I could use forwardRef in my Field in artlook because we're using an older version of redux-form), so I think what you have is the way to go.

I plan on getting a PR up for this today!

danparnella commented 3 years ago

@chawes13 I'm running into some bumps in the road represented by this issue. Does that make sense in that I need to define prop types and default props after exporting Textarea as a forwardRef?

chawes13 commented 3 years ago

@danparnella Did you try the solution outlined in this comment? https://github.com/facebook/react/issues/16653#issuecomment-564423981

I think you would want to do something like

const Input = React.forwardRef(function Input (props, ref) { return <input ref={ref} {...props} /> })
Input.propTypes = propTypes
Input.defaultProps = defaultProps

export default Input
danparnella commented 3 years ago

Got it, got it. Ok, just wanted to make sure I didn't go too off the rails with our patterns 👍 .

chawes13 commented 3 years ago

Uncharted territory 🤪