vue-maplibre-gl
Version:
Vue 3 plugin for maplibre-gl
85 lines (69 loc) • 2.42 kB
text/typescript
import { Position, type PositionProp, PositionValues } from '@/components/controls/position.enum';
import { usePositionWatcher } from '@/composable/usePositionWatcher';
import { isInitializedSymbol, mapSymbol } from '@/types';
import type { ControlPosition, IControl } from 'maplibre-gl';
import { createCommentVNode, defineComponent, h, inject, nextTick, onBeforeUnmount, type PropType, ref, type Ref, type SlotsType, Teleport, watch } from 'vue';
export class CustomControl implements IControl {
public static readonly CONTROL_CLASS = 'maplibregl-ctrl';
public static readonly CONTROL_GROUP_CLASS = 'maplibregl-ctrl-group';
public readonly container: HTMLDivElement;
constructor(private isAdded: Ref<boolean>, noClasses: boolean) {
this.container = document.createElement('div');
this.setClasses(noClasses);
}
getDefaultPosition(): ControlPosition {
return Position.TOP_LEFT;
}
onAdd(): HTMLElement {
nextTick(() => this.isAdded.value = true);
return this.container;
}
onRemove(): void {
this.isAdded.value = false;
this.container.remove();
}
setClasses(noClasses: boolean) {
if (noClasses) {
this.container.classList.remove(CustomControl.CONTROL_CLASS);
this.container.classList.remove(CustomControl.CONTROL_GROUP_CLASS);
} else {
this.container.classList.add(CustomControl.CONTROL_CLASS);
this.container.classList.add(CustomControl.CONTROL_GROUP_CLASS);
}
}
}
export default /*#__PURE__*/ defineComponent({
name : 'MglCustomControl',
props: {
position : {
type : String as PropType<PositionProp>,
validator: (v: Position) => {
return PositionValues.indexOf(v) !== -1;
}
},
noClasses: {
type : Boolean as PropType<boolean>,
default: false
}
},
slots: Object as SlotsType<{ default: {} }>,
setup(props, { slots }) {
const map = inject(mapSymbol)!,
isInitialized = inject(isInitializedSymbol)!,
isAdded = ref(false),
control = new CustomControl(isAdded, props.noClasses!);
usePositionWatcher(() => props.position, map, control);
watch(() => props.noClasses, v => control.setClasses(v!));
onBeforeUnmount(() => isInitialized.value && map.value?.removeControl(control));
return () => {
if (!isAdded.value) {
return createCommentVNode('custom-component');
}
return h(
Teleport as any,
{ to: control.container },
slots.default?.({})
);
};
}
});