forked from MapComplete/MapComplete
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 #2024
This commit is contained in:
parent
7038fcc6f6
commit
7d678d95c7
4 changed files with 54 additions and 18 deletions
|
@ -11,7 +11,7 @@ export default class SvelteUIElement<
|
||||||
Events extends Record<string, any> = any,
|
Events extends Record<string, any> = any,
|
||||||
Slots extends Record<string, any> = any
|
Slots extends Record<string, any> = any
|
||||||
> extends BaseUIElement {
|
> extends BaseUIElement {
|
||||||
private readonly _svelteComponent: {
|
public readonly _svelteComponent: {
|
||||||
new (args: {
|
new (args: {
|
||||||
target: HTMLElement
|
target: HTMLElement
|
||||||
props: Props
|
props: Props
|
||||||
|
@ -19,10 +19,11 @@ export default class SvelteUIElement<
|
||||||
slots?: Slots
|
slots?: Slots
|
||||||
}): SvelteComponentTyped<Props, Events, Slots>
|
}): SvelteComponentTyped<Props, Events, Slots>
|
||||||
}
|
}
|
||||||
private readonly _props: Props
|
public readonly _props: Props
|
||||||
private readonly _events: Events
|
public readonly _events: Events
|
||||||
private readonly _slots: Slots
|
public readonly _slots: Slots
|
||||||
private tag: "div" | "span" = "div"
|
private tag: "div" | "span" = "div"
|
||||||
|
public readonly isSvelte = true
|
||||||
|
|
||||||
constructor(svelteElement, props?: Props, events?: Events, slots?: Slots) {
|
constructor(svelteElement, props?: Props, events?: Events, slots?: Slots) {
|
||||||
super()
|
super()
|
||||||
|
@ -47,4 +48,18 @@ export default class SvelteUIElement<
|
||||||
})
|
})
|
||||||
return el
|
return el
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getClass(){
|
||||||
|
if(this.clss.size === 0){
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return this.clss
|
||||||
|
}
|
||||||
|
|
||||||
|
public getStyle(){
|
||||||
|
if(this.style === ""){
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return this.style
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import BaseUIElement from "../BaseUIElement.js"
|
import BaseUIElement from "../BaseUIElement.js"
|
||||||
import { onDestroy, onMount } from "svelte"
|
import { onDestroy, onMount } from "svelte"
|
||||||
|
import SvelteUIElement from "./SvelteUIElement"
|
||||||
|
|
||||||
export let construct: BaseUIElement | (() => BaseUIElement)
|
export let construct: BaseUIElement | (() => BaseUIElement)
|
||||||
let elem: HTMLElement
|
let elem: HTMLElement
|
||||||
let html: HTMLElement
|
let html: HTMLElement
|
||||||
|
let isSvelte = false
|
||||||
|
let uiElement : BaseUIElement | SvelteUIElement | undefined
|
||||||
|
let svelteElem: SvelteUIElement
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const uiElem = typeof construct === "function" ? construct() : construct
|
uiElement = typeof construct === "function" ? construct() : construct
|
||||||
html = uiElem?.ConstructElement()
|
|
||||||
|
if (uiElement?.["isSvelte"]) {
|
||||||
|
isSvelte = true
|
||||||
|
svelteElem = <SvelteUIElement> uiElement
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
html = uiElement?.ConstructElement()
|
||||||
|
|
||||||
if (html !== undefined) {
|
if (html !== undefined) {
|
||||||
elem?.replaceWith(html)
|
elem?.replaceWith(html)
|
||||||
|
@ -16,7 +27,12 @@
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
html?.remove()
|
html?.remove()
|
||||||
|
uiElement?.Destroy()
|
||||||
})
|
})
|
||||||
</script>
|
</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}
|
||||||
|
|
|
@ -63,7 +63,7 @@ export default abstract class BaseUIElement {
|
||||||
/**
|
/**
|
||||||
* Adds all the relevant classes, space separated
|
* Adds all the relevant classes, space separated
|
||||||
*/
|
*/
|
||||||
public SetClass(clss: string) {
|
public SetClass(clss: string): this {
|
||||||
if (clss == undefined) {
|
if (clss == undefined) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ export default abstract class BaseUIElement {
|
||||||
return this.clss.has(clss)
|
return this.clss.has(clss)
|
||||||
}
|
}
|
||||||
|
|
||||||
public SetStyle(style: string): BaseUIElement {
|
public SetStyle(style: string): this {
|
||||||
this.style = style
|
this.style = style
|
||||||
if (this._constructedHtmlElement !== undefined) {
|
if (this._constructedHtmlElement !== undefined) {
|
||||||
this._constructedHtmlElement.style.cssText = style
|
this._constructedHtmlElement.style.cssText = style
|
||||||
|
|
|
@ -50,13 +50,13 @@
|
||||||
center: { lng: lon, lat },
|
center: { lng: lon, lat },
|
||||||
maxZoom: 24,
|
maxZoom: 24,
|
||||||
interactive: true,
|
interactive: true,
|
||||||
attributionControl: false,
|
attributionControl: false
|
||||||
}
|
}
|
||||||
_map = new maplibre.Map(options)
|
_map = new maplibre.Map(options)
|
||||||
window.requestAnimationFrame(() => {
|
window.requestAnimationFrame(() => {
|
||||||
_map.resize()
|
_map.resize()
|
||||||
})
|
})
|
||||||
_map.on("load", function () {
|
_map.on("load", function() {
|
||||||
_map.resize()
|
_map.resize()
|
||||||
const canvas = _map.getCanvas()
|
const canvas = _map.getCanvas()
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
|
@ -71,13 +71,18 @@
|
||||||
map.set(_map)
|
map.set(_map)
|
||||||
})
|
})
|
||||||
onDestroy(async () => {
|
onDestroy(async () => {
|
||||||
await Utils.waitFor(250)
|
await Utils.waitFor(100)
|
||||||
try {
|
requestAnimationFrame(
|
||||||
if (_map) _map.remove()
|
() => {
|
||||||
map = null
|
try {
|
||||||
} catch (e) {
|
_map?.remove()
|
||||||
console.error("Could not destroy map")
|
console.log("Removed map")
|
||||||
}
|
map = null
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Could not destroy map")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue