spring-media / react-shadow-dom-retarget-events

https://www.npmjs.com/package/react-shadow-dom-retarget-events
84 stars 36 forks source link

onFocus event for <input> not working inside WebComponent #28

Open benrbray opened 4 years ago

benrbray commented 4 years ago

I want to use React inside the Shadow DOM of a web component. I'm calling retargetEvents on the shadow root, but unfortunately the onFocus event still isn't working as expected. However, other events like onClick are working just fine. Minimal working example below. (Using TypeScript 3.8.3, React 16.13, Parcel 1.12.4, react-shadow-dom-retarget-events 1.0.11).

Expected Behavior: When receiving focus, both text inputs should print a message to the console.

Actual Behavior: Only the input NOT inside a web component correctly prints the message. The input inside the web component does not print a message on focus.

Minimal Working Example:

TSX:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

import { init, GridGame } from '~/GridGame';

init();

import retargetEvents from "react-shadow-dom-retarget-events";

// WebComponent
export class InputFocusElement extends HTMLElement {
    constructor() {
        super();

        let shadowRoot = this.attachShadow({ mode: "open" });
        let template = document.createElement("div");
        shadowRoot.appendChild(template);

        ReactDOM.render(
            <InputFocusMWE />,
            template
        );

        // react-shadow-dom-retarget-events
        retargetEvents(shadowRoot);
    }
}

// React Component
interface IProps { }
class InputFocusMWE extends React.Component<IProps> {
    constructor(props: IProps) {
        super(props);
    }

    render() {
        return (
            <input
                type="text"
                onFocus={(evt) => { console.log("focus"); }}
                onClick={(evt) => { console.log("click"); }}
            />
        );
    }
}

customElements.define("input-mwe", InputFocusElement);

ReactDOM.render(
    <InputFocusMWE />,
    document.getElementById("no-component")
);

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello React!</title>
    </head>
    <body>
        <div>with component:</div>
        <input-mwe></input-mwe>
        <div>without component</div>
        <div id="no-component"></div>
        <script src="./index.tsx"></script>
    </body>
</html>
sTsaturian commented 3 years ago

In case anyone is still facing this problem, this happens because the onFocusIn event is not retargeted. It needs to be handled in the same way as onFocusOut.

minsohng commented 3 years ago

In case anyone is still facing this problem, this happens because the onFocusIn event is not retargeted. It needs to be handled in the same way as onFocusOut.

what's the way that handled onFocusOut? I am trying to fix onFocus issue as well.

sTsaturian commented 3 years ago

what's the way that handled onFocusOut? I am trying to fix onFocus issue as well.

The easiest fix is to add onFocusIn here, and onFocusIn: 'onFocus', here. Ot upgrade React to 17.x and eliminate the need for using the package.