missive / emoji-mart

🏪 One component to pick them all
https://missiveapp.com/open/emoji-mart
MIT License
8.69k stars 835 forks source link

Add `ref` and `searchRef` props #416

Open jonahparampara opened 4 years ago

jonahparampara commented 4 years ago

The picker seems to have a ref prop but it references the react component instead of the DOM component as expected.

Furthermore it would be really nice to export the search input ref as a searchRef prop.

In my case I want this so I can focus the search input on command (autoFocus doesn't suffice my use-case and I need more control)

jsheffers commented 4 years ago

I'm specifically interested in forwarding the ref mentioned above so that my useRef returns the DOM element instead of the react component. I'm unable to do a ref.current.contains(e.target) because the ref itself returns the component. This would give me the ability to see the user clicked inside of the picker. Is there another recommended way to do this with functional components?

jsheffers commented 4 years ago

FYI @jonahparampara. I was able to achieve what I wanted by creating a simple wrapping div and applying the ref to it. Not sure if that helps in your case.

Rafi993 commented 3 years ago

Hi I would like to have searchRef too. If this issue is not worked I can help with this :)

adlerfaulkner commented 3 years ago

I'm specifically interested in forwarding the ref mentioned above so that my useRef returns the DOM element instead of the react component. I'm unable to do a ref.current.contains(e.target) because the ref itself returns the component. This would give me the ability to see the user clicked inside of the picker. Is there another recommended way to do this with functional components?

I have this exact same use case. Would really like to have the ref to the DOM node.

s0-david commented 2 years ago

Any update on this?

jantonso commented 1 year ago

Agreed, would be very useful! I'd like to be able to manually call .focus({ preventScroll: true }) on the search input, so that the page doesn't scroll when I open the picker in a bootstrap popover.

jantonso commented 1 year ago

FYI @jonahparampara. I was able to achieve what I wanted by creating a simple wrapping div and applying the ref to it. Not sure if that helps in your case.

I had to do something similar for now. Adding a wrapper div with my ref, and then using that to manually focus the search input when the picker mounts:

useEffect(() => {

        // Find the root element of the shadow dom for the emoji picker
        const shadowRoot = emojiMartRef.current.querySelector('em-emoji-picker').shadowRoot;

        // Auto-focus the search input for the emoji picker
        if (shadowRoot) {

            // NOTE: Need to use timeout in order for the shadow root DOM elements to be queryable
            setTimeout(() => {

                shadowRoot.querySelector('input')?.focus({
                    preventScroll: true
               });

           }, 100);

        }

}, []);
tommoor commented 1 year ago

Thanks @jantonso – this is reasonable workaround. setTimeout shouldn't be needed with useLayoutEffect, but depends on your situation.