ToSvelte will now bind directly to svelte in the case that a SvelteUIElement is passed. This helps with cleaning up MapLibre maps, which should help with

This commit is contained in:
Pieter Vander Vennet 2024-07-16 14:45:29 +02:00
parent 7038fcc6f6
commit 7d678d95c7
4 changed files with 54 additions and 18 deletions

View file

@ -11,7 +11,7 @@ export default class SvelteUIElement<
Events extends Record<string, any> = any,
Slots extends Record<string, any> = any
> extends BaseUIElement {
private readonly _svelteComponent: {
public readonly _svelteComponent: {
new (args: {
target: HTMLElement
props: Props
@ -19,10 +19,11 @@ export default class SvelteUIElement<
slots?: Slots
}): SvelteComponentTyped<Props, Events, Slots>
}
private readonly _props: Props
private readonly _events: Events
private readonly _slots: Slots
public readonly _props: Props
public readonly _events: Events
public readonly _slots: Slots
private tag: "div" | "span" = "div"
public readonly isSvelte = true
constructor(svelteElement, props?: Props, events?: Events, slots?: Slots) {
super()
@ -47,4 +48,18 @@ export default class SvelteUIElement<
})
return el
}
public getClass(){
if(this.clss.size === 0){
return undefined
}
return this.clss
}
public getStyle(){
if(this.style === ""){
return undefined
}
return this.style
}
}

View file

@ -1,13 +1,24 @@
<script lang="ts">
import BaseUIElement from "../BaseUIElement.js"
import { onDestroy, onMount } from "svelte"
import SvelteUIElement from "./SvelteUIElement"
export let construct: BaseUIElement | (() => BaseUIElement)
let elem: HTMLElement
let html: HTMLElement
let isSvelte = false
let uiElement : BaseUIElement | SvelteUIElement | undefined
let svelteElem: SvelteUIElement
onMount(() => {
const uiElem = typeof construct === "function" ? construct() : construct
html = uiElem?.ConstructElement()
uiElement = typeof construct === "function" ? construct() : construct
if (uiElement?.["isSvelte"]) {
isSvelte = true
svelteElem = <SvelteUIElement> uiElement
return
}
html = uiElement?.ConstructElement()
if (html !== undefined) {
elem?.replaceWith(html)
@ -16,7 +27,12 @@
onDestroy(() => {
html?.remove()
uiElement?.Destroy()
})
</script>
<span bind:this={elem} />
{#if isSvelte}
<svelte:component this={svelteElem?._svelteComponent} {...svelteElem._props} class={svelteElem.getClass()} style={svelteElem.getStyle()}/>
{:else}
<span bind:this={elem} />
{/if}

View file

@ -63,7 +63,7 @@ export default abstract class BaseUIElement {
/**
* Adds all the relevant classes, space separated
*/
public SetClass(clss: string) {
public SetClass(clss: string): this {
if (clss == undefined) {
return this
}
@ -101,7 +101,7 @@ export default abstract class BaseUIElement {
return this.clss.has(clss)
}
public SetStyle(style: string): BaseUIElement {
public SetStyle(style: string): this {
this.style = style
if (this._constructedHtmlElement !== undefined) {
this._constructedHtmlElement.style.cssText = style

View file

@ -50,13 +50,13 @@
center: { lng: lon, lat },
maxZoom: 24,
interactive: true,
attributionControl: false,
attributionControl: false
}
_map = new maplibre.Map(options)
window.requestAnimationFrame(() => {
_map.resize()
})
_map.on("load", function () {
_map.on("load", function() {
_map.resize()
const canvas = _map.getCanvas()
if (interactive) {
@ -71,13 +71,18 @@
map.set(_map)
})
onDestroy(async () => {
await Utils.waitFor(250)
try {
if (_map) _map.remove()
map = null
} catch (e) {
console.error("Could not destroy map")
}
await Utils.waitFor(100)
requestAnimationFrame(
() => {
try {
_map?.remove()
console.log("Removed map")
map = null
} catch (e) {
console.error("Could not destroy map")
}
}
)
})
</script>