Files
Crussell/frontend/src/lib/components/ui/map/MarkerContent.svelte
T
popertotsandSisyphus 4c26db81db feat(frontend): add MapLibre GL map components
Reusable Svelte map component library wrapping MapLibre GL JS: Map, MapMarker, MapControls, MapPopup, MapRoute, MapClusterLayer, MapArc, and supporting components. Features theme auto-detection, controlled/uncontrolled viewport, drag support, and context API. useMap hook provides reactive access. Integrated on contact page for salon location display.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-04 01:07:25 +01:00

57 lines
1.5 KiB
Svelte

<script lang="ts">
import { getContext } from "svelte";
import MapLibreGL from "maplibre-gl";
import { cn } from "$lib/utils.js";
interface Props {
children?: import("svelte").Snippet;
class?: string;
}
let { children, class: className }: Props = $props();
const markerCtx = getContext<{
getMarker: () => MapLibreGL.Marker | null;
getElement: () => HTMLDivElement | null;
getMap: () => MapLibreGL.Map | null;
isReady: () => boolean;
}>("marker");
let wrapperElement: HTMLDivElement | null = $state(null);
let movedContent: Node[] = [];
// Move content to marker element when ready
$effect(() => {
const element = markerCtx.getElement();
const ready = markerCtx.isReady();
if (!ready || !element || !wrapperElement) return;
// Store and move children to marker element
movedContent = Array.from(wrapperElement.childNodes);
movedContent.forEach((child) => element.appendChild(child));
return () => {
// Move content back on cleanup
movedContent.forEach((child) => {
if (wrapperElement && child.parentNode === element) {
wrapperElement.appendChild(child);
}
});
movedContent = [];
};
});
</script>
<!-- Hidden wrapper that holds content until marker is ready -->
<div bind:this={wrapperElement} style="display: contents;">
<div class={cn("relative cursor-pointer", className)}>
{#if children}
{@render children()}
{:else}
<!-- Default marker icon -->
<div class="relative h-4 w-4 rounded-full border-2 border-white bg-blue-500 shadow-lg"></div>
{/if}
</div>
</div>