(map) add bidirectional interactivity between map and links

This commit is contained in:
Valentyne Stigloher 2024-05-30 14:58:58 +02:00
parent 2f0f482b46
commit 19c427f9d1
2 changed files with 45 additions and 10 deletions

View File

@ -9,6 +9,7 @@
<script lang="ts">
import type { PropType } from 'vue';
import dark from '../plugins/dark.ts';
import walsLanguages from '~/assets/languages.csv';
import polygonsByLocale from '~/assets/map.json';
@ -37,11 +38,23 @@ declare module 'leaflet' {
}
export default dark.extend({
props: {
highlightedLocale: { default: null, type: String as PropType<string | null> },
},
data() {
return {
polygons: {} as Record<string, L.Polygon[]>,
};
},
watch: {
highlightedLocale() {
for (const [locale, polygons] of Object.entries(this.polygons)) {
for (const polygon of polygons) {
polygon.setStyle({ fillOpacity: locale === this.highlightedLocale ? 1 : 0.2 });
}
}
},
},
async mounted() {
const { default: L } = await import('leaflet');
await import ('@elfalem/leaflet-curve');
@ -129,10 +142,10 @@ export default dark.extend({
}).addTo(map);
circle.bindTooltip(`<strong>${locale.name}</strong><br/>${clearUrl(locale.url)}`, { opacity: 1 });
circle.on('mouseover', () => {
this.polygons[locale.code].map((polygon) => polygon.setStyle({ fillOpacity: 1 }));
this.$emit('update', locale.code);
});
circle.on('mouseout', () => {
this.polygons[locale.code].map((polygon) => polygon.setStyle({ fillOpacity: 0.2 }));
this.$emit('update', null);
});
circle.on('click', () => {
window.open(locale.url);

View File

@ -1,7 +1,24 @@
<template>
<Page>
<div class="list-group d-flex flex-wrap flex-row my-4">
<a
v-for="(options, locale) in $locales"
:key="locale"
:href="options.url"
:class="['list-group-item', 'list-group-item-action', locale === highlightedLocale ? 'list-group-item-highlighted' : '', 'w-md-50']"
@mouseenter="highlightedLocale = locale"
@mouseleave="highlightedLocale = null"
>
<div class="h3">
<LocaleIcon :locale="options" class="mx-2" />
{{ options.name }}
<small v-if="options.extra" class="text-muted">({{ options.extra }})</small>
</div>
</a>
</div>
<template #below>
<LanguageMap />
<!-- @vue-ignore -->
<LanguageMap :highlighted-locale="highlightedLocale" @update="(locale) => highlightedLocale = locale" />
<p class="small text-muted my-3">
<Icon v="info-circle" />
The complexity of geographical reach of each language is represented in a simplified way
@ -11,17 +28,22 @@
</template>
</Page>
</template>
<script lang="ts">
import Vue from 'vue';
<script setup lang="ts">
export default Vue.extend({
data() {
return {
highlightedLocale: null as string | null,
};
},
});
</script>
<style lang="scss" scoped>
@import "assets/variables";
.list-group-item-hoverable {
&:hover {
color: $primary;
border-inline-start: 3px solid $primary;
padding-inline-start: calc(#{$list-group-item-padding-x} - 2px);
}
.list-group-item-highlighted {
border-left: 3px solid $primary !important;
padding-inline-start: calc(#{$list-group-item-padding-x} - 2px);
}
</style>