117 lines
3.4 KiB
Vue
117 lines
3.4 KiB
Vue
<script setup lang="ts">
|
||
import { computed } from 'vue'
|
||
import { UiButton } from '@/components/ui/button'
|
||
import { rarityClass } from '@/utils'
|
||
import increaseIcon from '@/assets/img/icon/increase.png'
|
||
import maxIcon from '@/assets/img/icon/max.png'
|
||
import minIcon from '@/assets/img/icon/min.png'
|
||
import reduceIcon from '@/assets/img/icon/reduce.png'
|
||
|
||
export type EquipmentLevelChange = 'preRarity' | 'nextRarity' | 'preLv' | 'nextLv'
|
||
|
||
const props = defineProps<{
|
||
rarity: string
|
||
level: number
|
||
rarityList: string[]
|
||
}>()
|
||
|
||
const emit = defineEmits<{
|
||
change: [direction: EquipmentLevelChange]
|
||
}>()
|
||
|
||
const rarityIndex = computed(() => props.rarityList.findIndex((rarity) => rarity === props.rarity))
|
||
const atFirstRarity = computed(() => rarityIndex.value <= 0)
|
||
const atLastRarity = computed(() => rarityIndex.value >= props.rarityList.length - 1)
|
||
|
||
function formatLevel(level: number, rarity: string) {
|
||
if (rarity === '太初') return ''
|
||
const greekNumerals = ['Ι', 'ΙΙ', 'ΙΙΙ', 'ΙV', 'V', 'VΙ', 'VΙΙ', 'VΙΙΙ', 'ΙX', 'X']
|
||
return greekNumerals[level - 1] || level.toString()
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div class="equipment-level-controls" aria-label="装备等级">
|
||
<UiButton
|
||
size="icon"
|
||
title="降低品质"
|
||
aria-label="降低品质"
|
||
:disabled="atFirstRarity"
|
||
@click="emit('change', 'preRarity')"
|
||
>
|
||
<img data-icon class="equipment-level-controls__icon" :src="minIcon" alt="" />
|
||
</UiButton>
|
||
<UiButton
|
||
size="icon"
|
||
title="降低等级"
|
||
aria-label="降低等级"
|
||
:disabled="atFirstRarity && level <= 1"
|
||
@click="emit('change', 'preLv')"
|
||
>
|
||
<img data-icon class="equipment-level-controls__icon" :src="reduceIcon" alt="" />
|
||
</UiButton>
|
||
|
||
<output class="equipment-level-controls__value" :class="rarityClass(rarity)">
|
||
<span>{{ rarity }}</span>
|
||
<span>{{ formatLevel(level, rarity) }}</span>
|
||
</output>
|
||
|
||
<UiButton
|
||
size="icon"
|
||
title="提升等级"
|
||
aria-label="提升等级"
|
||
:disabled="atLastRarity"
|
||
@click="emit('change', 'nextLv')"
|
||
>
|
||
<img data-icon class="equipment-level-controls__icon" :src="increaseIcon" alt="" />
|
||
</UiButton>
|
||
<UiButton
|
||
size="icon"
|
||
title="提升品质"
|
||
aria-label="提升品质"
|
||
:disabled="atLastRarity"
|
||
@click="emit('change', 'nextRarity')"
|
||
>
|
||
<img data-icon class="equipment-level-controls__icon" :src="maxIcon" alt="" />
|
||
</UiButton>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.equipment-level-controls {
|
||
box-sizing: border-box;
|
||
display: flex;
|
||
min-width: 0;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--ui-autocomplete-trigger-gap);
|
||
padding: var(--ui-disclosure-content-padding-block);
|
||
background: var(--ui-settings-row-alt);
|
||
}
|
||
|
||
.equipment-level-controls__value {
|
||
display: flex;
|
||
min-width: 0;
|
||
min-height: var(--ui-control-height-default);
|
||
flex: 1;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: var(--ui-control-gap);
|
||
padding-inline: var(--ui-control-padding-inline-compact);
|
||
border: 1px solid var(--ui-disclosure-border);
|
||
background: var(--ui-field-background);
|
||
line-height: var(--ui-control-line-height);
|
||
}
|
||
|
||
.equipment-level-controls__icon {
|
||
width: var(--ui-badge-height);
|
||
height: var(--ui-badge-height);
|
||
object-fit: contain;
|
||
}
|
||
|
||
:deep(.ui-button:disabled) .equipment-level-controls__icon {
|
||
filter: grayscale(1);
|
||
opacity: var(--ui-control-disabled-opacity, var(--ui-settings-dropdown-disabled-opacity));
|
||
}
|
||
</style>
|