The Experimental maps' explainer lived in a "?" floating at the top centre of the app, which read as a game piece rather than part of the map. The map already has a "?" control. This lets that control answer from the HOST: a click dispatches doxa:help, bubbling and composed, so it crosses every shadow root between the button and the page, and the app answers with the map's text. library/composables/useHostedHelp.js is the one mechanism, for the HelpButton map control and for the maps whose "?" belongs in their own bar. It also decides WHERE the button shows: only under a host that answers (an ancestor, across shadow roots, carrying data-doxa-help), so the same bundle embedded on a partner page shows no dead "?". HelpButton keeps its open-help emit, so doxa-simple-map's own help popup is unchanged; hosted is opt-in.
47 lines
1.7 KiB
Vue
47 lines
1.7 KiB
Vue
<!--
|
|
HelpButton.vue — the map's "?" control: what this map is and how to use it.
|
|
|
|
One click, two ways to answer it:
|
|
- `open-help` (emit): the map shows its own help (doxa-simple-map's popup does).
|
|
- `doxa:help` (a DOM event, bubbling and COMPOSED; see composables/useHostedHelp.js): a HOST
|
|
answers for the map. The Doxa Maps app (doxa-maps-spa) answers with the Experimental shelf's
|
|
what/how text, which is how that explainer left the top of the screen for the map's own control
|
|
column, next to zoom and fullscreen.
|
|
|
|
Props:
|
|
isDark — theme flag forwarded from parent
|
|
hosted — show the button ONLY under a host that answers doxa:help. A map whose help lives in its
|
|
host sets this, so the same bundle embedded on a page with no such host shows no dead "?".
|
|
|
|
Emits:
|
|
open-help — fires on click; parent decides how to display help content
|
|
-->
|
|
<script setup>
|
|
import { computed } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import MapControlButton from './MapControlButton.vue'
|
|
import { useHostedHelp } from '../../composables/useHostedHelp.js'
|
|
|
|
const { t } = useI18n()
|
|
|
|
const props = defineProps({
|
|
isDark: { type: Boolean, default: false },
|
|
hosted: { type: Boolean, default: false }
|
|
})
|
|
|
|
const emit = defineEmits(['open-help'])
|
|
|
|
const { hosted: underHost, askForHelp } = useHostedHelp()
|
|
const shown = computed(() => !props.hosted || underHost.value)
|
|
|
|
function onClick() {
|
|
emit('open-help')
|
|
askForHelp()
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<MapControlButton v-if="shown" data-control="help" :is-dark="isDark" :title="t('buttons.aboutThisMap')" @click="onClick">
|
|
<span style="font-size:15px;font-weight:700;font-family:serif;line-height:1;">?</span>
|
|
</MapControlButton>
|
|
</template>
|