mapbox / mapbox-gl-geocoder

Geocoder control for mapbox-gl-js using Mapbox Geocoding API
https://mapbox.com/mapbox-gl-js/example/mapbox-gl-geocoder/
ISC License
362 stars 181 forks source link

react compatibility react.createElement and eventEmitter based HTMLElement #526

Open wibed opened 6 months ago

wibed commented 6 months ago

afaik geocoder produces an wrapped input htmlelement which i am unable to convert into a viable react.element.

i tried something along those lines:


        const geocoderNode: HTMLElement = ctrl.onAdd(mapboxMap)

        const geocoderInputChildren = Array.from(geocoderNode.children).filter(el => el.tagName.toLowerCase() === "input")
        if (geocoderInputChildren.length === 0) { throw new Error("missing input element") }
        const geocoderInput: HTMLInputElement = geocoderInputChildren[0] as HTMLInputElement

        const geocoderInputNode = React.createElement(
          geocoderInput.tagName.toLowerCase(),
          { class: geocoderInput.className, type: "text", placeholder: "Search", ariaLabel: "Search" }
        )

        const GeocoderNode: JSX.Element = React.createElement(
          geocoderNode.tagName.toLowerCase(), 
          { className: geocoderNode.classList },
          geocoderInputNode
        )

but done this way any connection to the events are lost.

only when i use above example like this i am able to keep the events

        ...
        const geocoderNode: HTMLElement = ctrl.onAdd(mapboxMap)
        containerNode.appendChild(geocoderNode)
        ...

which breaks compatibility with react and its virtual dom.

how can i work around this to keep functionality and react compatibility?

why bother? you might ask. id like to control the results from the input element via react-hook-form but unable to do so due to lack of compatibility.

wibed commented 6 months ago

i have all these events within the browser: image

yet cant make out a single one within programatically id access them like this

        const geocoderNode = ctrl.onAdd(mapboxMap)
        // START INSPECTION HERE BUT...
        const geocoderInputChildren = Array.from(geocoderNode.children).filter(el => el.tagName.toLowerCase() === "input")
        if (geocoderInputChildren.length === 0) { throw new Error("missing input") }
        const geocoderInput= geocoderInputChildren[0]
        // ...CANT FIND ANY EVENTS PROGRAMMATICALLY
        containerNode.appendChild(geocoderNode)

what could be the reason i am trying to copy the events over from a htmlelement into a compatible react element i tried using the following

        const geocoderInputNode = React.createElement(
          geocoderInput.tagName.toLowerCase(),
          { className: geocoderInput.className, type: "text", placeholder: "Search", "aria-label": "Search" }
        )

        const GeocoderNode: JSX.Element = React.createElement(
          geocoderNode.tagName.toLowerCase(), 
          { className: geocoderNode.classList },
          geocoderInputNode
        )

expected to be successfull but ended up with these events instead image