Use radio buttons for map list

This commit is contained in:
James Lyne 2021-05-27 19:16:45 +01:00
parent e1c56c201e
commit e3f64e720c
4 changed files with 46 additions and 46 deletions

View File

@ -51,8 +51,9 @@ export default {
<style> <style>
.svg-icon { .svg-icon {
fill: currentColor; pointer-events: none;
height: 24px; fill: currentColor;
width: 24px; height: 24px;
width: 24px;
} }
</style> </style>

View File

@ -20,7 +20,7 @@
<li role="none"> <li role="none">
<button type="button" role="menuitem" @click.prevent="pan">{{ messageCenterHere }}</button> <button type="button" role="menuitem" @click.prevent="pan">{{ messageCenterHere }}</button>
</li> </li>
<WorldListItem v-if="currentWorld" :world="currentWorld"></WorldListItem> <WorldListItem v-if="currentWorld" :world="currentWorld" name="context"></WorldListItem>
</ul> </ul>
</nav> </nav>
</template> </template>

View File

@ -18,10 +18,10 @@
<CollapsibleSection name="maps"> <CollapsibleSection name="maps">
<template v-slot:heading>{{ heading }}</template> <template v-slot:heading>{{ heading }}</template>
<template v-slot:default> <template v-slot:default>
<ul class="section__content" role="listbox"> <RadioList class="section__content">
<WorldListItem :world="world" v-for="[name, world] in worlds" :key="name"></WorldListItem> <WorldListItem :world="world" v-for="[name, world] in worlds" :key="`${prefix}_${currentServer.id}_${name}`"></WorldListItem>
<li v-if="!worlds.size" class="section__skeleton">{{ skeletonWorlds }}</li> <span v-if="!worlds.size" class="section__skeleton">{{ skeletonWorlds }}</span>
</ul> </RadioList>
</template> </template>
</CollapsibleSection> </CollapsibleSection>
</template> </template>
@ -31,10 +31,12 @@ import WorldListItem from './WorldListItem.vue';
import {defineComponent} from 'vue'; import {defineComponent} from 'vue';
import {useStore} from "@/store"; import {useStore} from "@/store";
import CollapsibleSection from "@/components/sidebar/CollapsibleSection.vue"; import CollapsibleSection from "@/components/sidebar/CollapsibleSection.vue";
import RadioList from "@/components/util/RadioList.vue";
export default defineComponent({ export default defineComponent({
name: 'WorldList', name: 'WorldList',
components: { components: {
RadioList,
CollapsibleSection, CollapsibleSection,
WorldListItem WorldListItem
}, },
@ -50,6 +52,10 @@ export default defineComponent({
worlds() { worlds() {
return useStore().state.worlds; return useStore().state.worlds;
},
currentServer() {
return useStore().state.currentServer;
} }
} }
}); });

View File

@ -15,23 +15,22 @@
--> -->
<template> <template>
<li class="world" role="none"> <div class="world">
<span class="world__name">{{ world.title }}</span> <span class="world__name">{{ world.title }}</span>
<ul class="world__maps" role="menu"> <div class="world__maps menu">
<li :class="{'map': true, 'map--selected': map === currentMap}" v-for="[name, map] in world.maps" :key="name" role="none"> <template v-for="[key, map] in world.maps" :key="`${world.name}_${key}`">
<button role="menuitemradio" type="button" :title="`${world.title} - ${map.title}`" <input :id="`${name}-${world.name}-${key}`" type="radio" :name="name" v-bind:value="map" v-model="currentMap">
@click="setCurrentMap(map.name)" :aria-label="`${world.title} - ${map.title}`" <label class="map" :for="`${name}-${world.name}-${key}`" :title="`${world.title} - ${map.title}`">
:aria-checked="map === currentMap">
<SvgIcon :name="getMapIcon(map)"></SvgIcon> <SvgIcon :name="getMapIcon(map)"></SvgIcon>
</button> </label>
</li> </template>
</ul> </div>
</li> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import {useStore} from "@/store"; import {useStore} from "@/store";
import {DynmapWorldMap, DynmapWorld} from "@/dynmap"; import {DynmapWorld, DynmapWorldMap} from "@/dynmap";
import {defineComponent} from 'vue'; import {defineComponent} from 'vue';
import {MutationTypes} from "@/store/mutation-types"; import {MutationTypes} from "@/store/mutation-types";
import SvgIcon from "@/components/SvgIcon.vue"; import SvgIcon from "@/components/SvgIcon.vue";
@ -54,13 +53,22 @@ export default defineComponent({
world: { world: {
type: Object as () => DynmapWorld, type: Object as () => DynmapWorld,
required: true required: true
},
name: {
type: String,
default: 'map',
} }
}, },
computed: { computed: {
currentMap(): DynmapWorldMap | undefined { currentMap: {
return useStore().state.currentMap; get() {
}, return useStore().state.currentMap;
},
set(value) {
useStore().commit(MutationTypes.SET_CURRENT_MAP, {worldName: this.world.name, mapName: value.name});
}
}
}, },
methods: { methods: {
@ -80,12 +88,6 @@ export default defineComponent({
} }
return `block_${worldType}_${mapType}`; return `block_${worldType}_${mapType}`;
},
setCurrentMap(mapName: string) {
useStore().commit(MutationTypes.SET_CURRENT_MAP, {
worldName: this.world.name,
mapName
});
} }
} }
}); });
@ -96,6 +98,7 @@ export default defineComponent({
display: flex; display: flex;
align-items: center; align-items: center;
margin-bottom: .5rem; margin-bottom: .5rem;
padding-left: 0.8rem;
.world__name { .world__name {
word-break: break-word; word-break: break-word;
@ -116,27 +119,17 @@ export default defineComponent({
width: 3.2rem; width: 3.2rem;
height: 3.2rem; height: 3.2rem;
button { .svg-icon {
display: block; top: 0.2rem !important;
height: 100%; right: 0.2rem !important;
width: 100%; bottom: 0.2rem !important;
border-radius: 0.5rem; left: 0.2rem !important;
width: calc(100% - 0.4rem) !important;
.svg-icon { height: auto !important;
top: 0.2rem;
right: 0.2rem;
bottom: 0.2rem;
left: 0.2rem;
width: calc(100% - 0.4rem);
}
} }
& + .map { & ~ .map {
margin-left: 0.5rem; margin-left: 0.5rem;
} }
&.map--selected button {
background-color: var(--background-hover);
}
} }
</style> </style>