I have a React app and I want to use a reusable JS web component that is supposed to output a <dialog> with content cloned from HTML inserted into the <custom-tag> of same JS component.
The HTML I want to clone has an <input type="file"> with an `onChange' event.
Once the JS component renders the <dialog> with the cloned HTML the onChange event gets lost and nothing happens as expected.
I'm looking for a way to NOT loose any of the events on any inputs and/or buttons passed on to the JS component.
I will provide code samples and a link to a GitHub repo.
https://github.com/ChidoYo/dialog-component.git
App.tsx
import React from 'react';
import './App.css';
import './webComponent/dialog_component'
declare global {
namespace JSX {
interface IntrinsicElements {
"dialog-component": DialogComponentProps;
}
}
}
interface DialogComponentProps
extends React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
> {
trigger: string;
target: string;
}
function App() {
return (
<div>
<h1>¡Hola!</h1>
<div className='sample'>
<p>Plain File Input</p>
Upload
<input
type="file"
id="plain"
className='input-file'
onChange={() => console.log('Outside Dialog')}
accept="image/jpeg, image/png"
/>
</div>
<button className="btn-open" id="openDialog">Open Modal</button>
<dialog-component id="dialogSample" trigger="openDialog" target="myDialog">
<div>
<p>File Upload in Dialog</p>
<label htmlFor="outter-one" className='input-label'>
Upload Picture
<input
type="file"
id="outter-one"
className='input-file'
accept="image/jpeg, image/png"
onChange={() => console.log('Inside Component')}
/>
</label>
</div>
</dialog-component>
</div>
);
}
export default App;
JS Web Component
class DialogComponent extends HTMLElement {
connectedCallback() {
const id = this.getAttribute('id')
const trigger = this.getAttribute('trigger')
const target = this.getAttribute('target')
let dialogChildren = document.getElementById(id).firstChild.cloneNode(true)
dialogChildren = dialogChildren.innerHTML
console.log('dialogChildren', dialogChildren);
const dialogContent = `
<dialog id="${target}">
<span class="icon"></span>
<div class="text-content">
${dialogChildren}
</div>
<button class="btn-close" close-dialog autofocus>Close Modal</button>
</dialog>
`
this.innerHTML = dialogContent
// Open Dialog
const openButton = document.getElementById(trigger)
const closeButton = this.querySelector('[close-dialog]')
const dialog = this.querySelector(`#${target}`)
openButton.addEventListener('click', e => {
e.preventDefault()
dialog.showModal()
})
closeButton.addEventListener('click', () => dialog.close())
}
}
customElements.define('dialog-component', DialogComponent)