diff --git a/examples/snowbox/index.html b/examples/snowbox/index.html
index 79a0317df1..14ee71a948 100644
--- a/examples/snowbox/index.html
+++ b/examples/snowbox/index.html
@@ -58,6 +58,7 @@
POLAR map client
+
Coordinates of currently selected feature:
diff --git a/examples/snowbox/index.js b/examples/snowbox/index.js
index ea0bc33808..44dc6c16ed 100644
--- a/examples/snowbox/index.js
+++ b/examples/snowbox/index.js
@@ -572,3 +572,16 @@ document
colorScheme = colorScheme === 'light' ? 'dark' : 'light'
updateState(map, 'core', 'colorScheme', colorScheme)
})
+
+let filterItem = null
+document
+ .getElementById('toggle-filter')
+ .addEventListener('click', ({ target }) => {
+ const store = getStore(map, 'iconMenu')
+ if (!filterItem) {
+ ;[filterItem] = store.menus.splice(1, 1)
+ } else {
+ store.menus.splice(1, 0, filterItem)
+ filterItem = null
+ }
+ })
diff --git a/src/plugins/filter/store.ts b/src/plugins/filter/store.ts
index 340db586c6..23eb01dd62 100644
--- a/src/plugins/filter/store.ts
+++ b/src/plugins/filter/store.ts
@@ -52,10 +52,12 @@ export const useFilterStore = defineStore('plugins/filter', () => {
{ deep: true, immediate: true }
)
)
+ teardownCallbacks.push(callback)
})
}
function teardownPlugin() {
+ filterMainStore.state = {}
teardownCallbacks.forEach((callback) => {
callback()
})
diff --git a/src/plugins/iconMenu/components/NineRegionsButton.ce.vue b/src/plugins/iconMenu/components/NineRegionsButton.ce.vue
index 8bb25a50d5..e7ec75ee16 100644
--- a/src/plugins/iconMenu/components/NineRegionsButton.ce.vue
+++ b/src/plugins/iconMenu/components/NineRegionsButton.ce.vue
@@ -13,7 +13,6 @@ import { storeToRefs } from 'pinia'
import { computed, inject } from 'vue'
import PolarIconButton from '@/components/PolarIconButton.ce.vue'
-import { useCoreStore } from '@/core/stores'
import { useIconMenuStore } from '../store'
@@ -30,13 +29,7 @@ const active = computed(() => open.value === props.id)
const updateMaxWidth = inject('updateMaxWidth') as () => void
function toggle() {
- if (open.value === props.id) {
- open.value = null
- useCoreStore().setMoveHandle(null)
- } else {
- open.value = props.id
- iconMenuStore.openInMoveHandle(props.id)
- }
+ open.value = open.value === props.id ? null : props.id
updateMaxWidth()
}
diff --git a/src/plugins/iconMenu/components/StandardMenuList.ce.vue b/src/plugins/iconMenu/components/StandardMenuList.ce.vue
index 1b0df4448f..3485ee63f9 100644
--- a/src/plugins/iconMenu/components/StandardMenuList.ce.vue
+++ b/src/plugins/iconMenu/components/StandardMenuList.ce.vue
@@ -122,13 +122,7 @@ function updateMaxWidth() {
}
function toggle(id: string) {
- if (open.value === id) {
- open.value = null
- coreStore.setMoveHandle(null)
- } else {
- open.value = id
- iconMenuStore.openInMoveHandle(id)
- }
+ open.value = open.value === id ? null : id
updateMaxWidth()
}
diff --git a/src/plugins/iconMenu/store.ts b/src/plugins/iconMenu/store.ts
index 30a638d72c..64335a3e77 100644
--- a/src/plugins/iconMenu/store.ts
+++ b/src/plugins/iconMenu/store.ts
@@ -4,14 +4,13 @@
*/
/* eslint-enable tsdoc/syntax */
-import type { Component } from 'vue'
import type { Icon } from '@/core'
import type { Menu } from './types'
import { toMerged } from 'es-toolkit'
import { t } from 'i18next'
import { acceptHMRUpdate, defineStore } from 'pinia'
-import { computed, markRaw, ref } from 'vue'
+import { computed, markRaw, ref, watch } from 'vue'
import { useCoreStore } from '@/core/stores'
@@ -42,6 +41,33 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => {
() => coreStore.configuration.iconMenu?.layoutTag ?? ''
)
+ const flatMenuItems = computed(() =>
+ menus.value.concat(focusMenus.value).flat()
+ )
+ watch(
+ flatMenuItems,
+ (newItems, oldItems) => {
+ const getDiffItems = (to, from) =>
+ to.filter(
+ (item) =>
+ !from.some((oldItem) => oldItem.plugin.id === item.plugin.id)
+ )
+ getDiffItems(newItems, oldItems).forEach((newItem) => {
+ coreStore.addPlugin(toMerged(newItem.plugin, { independent: false }))
+ })
+ getDiffItems(oldItems, newItems).forEach((oldItem) => {
+ if (open.value === oldItem.plugin.id) {
+ open.value = null
+ }
+ if (focusOpen.value === oldItem.plugin.id) {
+ focusOpen.value = null
+ }
+ coreStore.removePlugin(oldItem.plugin.id)
+ })
+ },
+ { deep: true }
+ )
+
function setupPlugin() {
menus.value = (coreStore.configuration.iconMenu?.menus || []).map(
(menuGroup) =>
@@ -64,24 +90,6 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => {
coreStore.addPlugin(toMerged(plugin, { independent: false }))
})
- // Otherwise, the component itself is made reactive
- menus.value.map((menuGroup) =>
- menuGroup.map((menuItem) =>
- toMerged(menuItem, {
- plugin: {
- component: markRaw(menuItem.plugin.component as Component),
- },
- })
- )
- )
- focusMenus.value.map((menuItem) =>
- toMerged(menuItem, {
- plugin: {
- component: markRaw(menuItem.plugin.component as Component),
- },
- })
- )
-
const initiallyOpen = coreStore.configuration.iconMenu?.initiallyOpen
if (
!coreStore.hasSmallHeight &&
@@ -104,21 +112,31 @@ export const useIconMenuStore = defineStore('plugins/iconMenu', () => {
function openMenuById(openId: string) {
const entry = menus.value.flat().find(({ plugin: { id } }) => id === openId)
-
if (entry) {
open.value = openId
- openInMoveHandle(openId)
}
}
+ watch(open, (open) => {
+ if (open) {
+ openInMoveHandle(open)
+ } else {
+ coreStore.setMoveHandle(null)
+ }
+ })
function openFocusMenuById(openId: string) {
const entry = focusMenus.value.find(({ plugin: { id } }) => id === openId)
-
if (entry) {
focusOpen.value = openId
- openInMoveHandle(openId, true)
}
}
+ watch(focusOpen, (focusOpen) => {
+ if (focusOpen) {
+ openInMoveHandle(focusOpen, true)
+ } else {
+ coreStore.setMoveHandle(null)
+ }
+ })
function openInMoveHandle(openId: string, focusMenu = false) {
const menu = (focusMenu ? focusMenus.value : menus.value.flat()).find(