feat(WIP): 턴 선택기를 multiselect에서 modal form으로 변경
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<teleport to="body">
|
||||
<div v-if="showForm">
|
||||
<div class="commandCategory">
|
||||
<div
|
||||
class="categoryItem"
|
||||
v-for="[categoryKey, { deco: categoryDeco }] of commandList"
|
||||
:key="categoryKey"
|
||||
><BButton @click="chosenCategory=categoryKey">{{ categoryDeco.altName ?? categoryDeco.name }}</BButton></div>
|
||||
</div>
|
||||
<div class="commandList">
|
||||
<div
|
||||
class="commandItem"
|
||||
v-for="commandItem of chosenSubList"
|
||||
:key="commandItem.value"
|
||||
@click="close(commandItem.value)"
|
||||
>
|
||||
{{ commandItem.simpleName }}
|
||||
<br />
|
||||
<small>{{ commandItem.title }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="commandBottom">
|
||||
<BButton @click="close()">닫기</BButton>
|
||||
</div>
|
||||
</div>
|
||||
</teleport>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
/*
|
||||
<template v-if="props.option.title">
|
||||
<span class="compensatePositive" v-if="props.option.compensation > 0">▲</span>
|
||||
<span class="compensateNegative" v-else-if="props.option.compensation < 0">▼</span>
|
||||
<span class="compensateNeutral" v-else></span>
|
||||
<span
|
||||
:class="[props.option.possible ? '' : 'commandImpossible']"
|
||||
>{{ props.option.title }}</span>
|
||||
</template>
|
||||
<template v-else-if="props.option.category">{{ props.option.category }}</template>
|
||||
</template>
|
||||
<template v-slot:singleLabel="props">{{ props.option.simpleName }}</template>
|
||||
*/
|
||||
import type { CommandItem } from "@/defs";
|
||||
import { BButton } from "bootstrap-vue-3";
|
||||
import { ref, defineProps, defineEmits, defineExpose, type PropType, watch } from "vue";
|
||||
|
||||
const chosenCategory = ref<string>("");
|
||||
const chosenSubList = ref<CommandItem[]>([]);
|
||||
|
||||
interface CategoryDecoration {
|
||||
name: string,
|
||||
altName?: string,
|
||||
//icon?: string,
|
||||
//color?: string,
|
||||
//backgroundColor?: string,
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
categoryInfo: {
|
||||
type: Object as PropType<Record<string, Omit<CategoryDecoration, 'name'>>>,
|
||||
required: false,
|
||||
},
|
||||
commandList: {
|
||||
type: Object as PropType<{
|
||||
category: string;
|
||||
values: CommandItem[];
|
||||
}[]>,
|
||||
required: true,
|
||||
}
|
||||
})
|
||||
|
||||
const showForm = ref(false);
|
||||
|
||||
function convCategoryDeco(category: string): CategoryDecoration {
|
||||
const itemInfo = props.categoryInfo?.[category];
|
||||
if (!itemInfo) {
|
||||
return {
|
||||
name: category,
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: category,
|
||||
...itemInfo
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
const commandList = ref(new Map<string, {
|
||||
deco: CategoryDecoration,
|
||||
values: CommandItem[],
|
||||
}>());
|
||||
|
||||
function updateCommandList(rawCommandList: typeof props.commandList) {
|
||||
commandList.value.clear();
|
||||
for (const { category, values } of rawCommandList) {
|
||||
commandList.value.set(category, {
|
||||
deco: convCategoryDeco(category),
|
||||
values
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => props.commandList, updateCommandList);
|
||||
updateCommandList(props.commandList);
|
||||
|
||||
watch(chosenCategory, (category) => {
|
||||
console.log('sel', category);
|
||||
const itemInfo = commandList.value?.get(category);
|
||||
if (itemInfo === undefined) {
|
||||
console.error(`category 없음: ${category}`);
|
||||
return;
|
||||
}
|
||||
chosenSubList.value = itemInfo.values;
|
||||
});
|
||||
|
||||
function show(): void {
|
||||
showForm.value = true;
|
||||
}
|
||||
|
||||
function close(category?: string): void {
|
||||
showForm.value = false;
|
||||
emits('onClose', category);
|
||||
}
|
||||
|
||||
const emits = defineEmits<{
|
||||
(event: 'onClose', command?: string): void,
|
||||
}>();
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
close
|
||||
})
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user