Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

focus() does not work on a controlled textarea input #784

Closed
punkpeye opened this issue Sep 20, 2024 · 2 comments · Fixed by #785
Closed

focus() does not work on a controlled textarea input #784

punkpeye opened this issue Sep 20, 2024 · 2 comments · Fixed by #785

Comments

@punkpeye
Copy link

punkpeye commented Sep 20, 2024

Describe the bug and the expected behavior

I am trying to focus a textarea input using focus(), but it does not do anything.

Conform version

v1.2.2

Steps to Reproduce the Bug or Issue

() => {
  const historyState = useHistoryState<string>('');

  const fetcher = useFetcher<typeof action>();

  const [form, fields] = useForm({
    defaultValue: {
      message: '',
    },
    lastResult: fetcher.data?.submission,
  });

  const formRef = useRef<HTMLFormElement>(null);

  const messageInputControl = useInputControl(fields.message);

  const formProps = getFormProps(form);

  useEffect(() => {
    if (historyState.state !== messageInputControl.value) {
      messageInputControl.change(historyState.state);
    }
  }, [messageInputControl, historyState.state]);

  useEffect(() => {
    if (!chatSession.focused) {
      return;
    }

    console.log('this fires');

    messageInputControl.focus();
  }, [chatSession.focused, messageInputControl]);

  return (
    <fetcher.Form
      action={getPath('/api/chat/:uid/send-message', {
        uid: chatSession.uid,
      })}
      method="post"
      ref={formRef}
      {...formProps}
    >
      <textarea
        className={css({
          _focus: {
            border: '1px solid #00d992',
            boxShadow: 'none',
          },
        })}
        {...getTextareaProps(fields.message)}
      />
    </fetcher.Form>
  );
};

What browsers are you seeing the problem on?

No response

Screenshots or Videos

No response

Additional context

I am seeing the "this fires" event logged, but textarea is never focused.

@edmundhung
Copy link
Owner

Hi @punkpeye, thanks for your question! It looks like there was some confusion about the focus() method from useInputControl(). The key thing to note is that input.focus() simulates the browser's focus and focusin events, but it does not actually move the focus to the input element itself.

If you want to programmatically move the focus to an input field, you'll need to use the native DOM method, like inputElement.focus(), e.g.

function Example() {
  const textareaRef = useRef();

  useEffect(() => {
    if (!chatSession.focused) {
      return;
    }

    textareaRef.current.focus();
  }, [chatSession.focused, messageInputControl]);

  return (
      <textarea
        className={css({
          _focus: {
            border: '1px solid #00d992',
            boxShadow: 'none',
          },
        })}
        {...getTextareaProps(fields.message)}
        ref={textareaRef}
      />
  );
};

I've also created a PR to improve the documentation based on this, so feel free to take a look and let me know if it's still confusing or if you have more suggestions. I appreciate the feedback!

Let me know if that clears things up or if you have more questions!

@punkpeye
Copy link
Author

This makes sense. Documentation improvements definitely help.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants