Files
dcalc/frontendNew/src/pages/Dcalc/Character/EquipmentDictionary/components/EquipmentCell.vue
T
2026-07-11 11:14:12 +08:00

84 lines
2.1 KiB
Vue

<script setup lang="ts">
import { computed } from "vue";
import type { IEquipment } from "@/api/info/type";
import { getImageURL } from "@/utils";
import { cn } from "@/lib/utils";
const props = defineProps<{
equipment?: IEquipment;
inactive?: boolean;
selected?: boolean;
useDisplayUrl?: boolean;
}>();
defineEmits<{
click: [];
preview: [];
rightClick: [];
}>();
const rarityClass = computed(() => {
switch (props.equipment?.rarity) {
case "稀有":
return "border-violet-400";
case "神器":
return "border-fuchsia-500";
case "传说":
return "border-orange-500";
case "史诗":
return "border-amber-400";
case "太初":
return "border-emerald-400";
default:
return "border-muted";
}
});
const imageUrl = computed(() => {
if (!props.equipment) return "";
const path = props.useDisplayUrl ? props.equipment.displayUrl : props.equipment.imageUrl;
return path ? getImageURL(path) : "";
});
const cellStyle = {
width: "var(--equip-cell-size, 1.75rem)",
height: "var(--equip-cell-size, 1.75rem)",
};
</script>
<template>
<button
v-if="equipment"
type="button"
:class="
cn(
'relative shrink-0 overflow-hidden rounded-sm border bg-background p-0 leading-none transition-colors',
rarityClass,
selected
? 'after:pointer-events-none after:absolute after:inset-0 after:rounded-[3px] after:shadow-[inset_0_0_0_2px_hsl(var(--primary)),0_0_0_1px_hsl(var(--background))]'
: 'hover:border-primary/60',
inactive ? 'opacity-60' : '',
)
"
:style="cellStyle"
@click="$emit('click')"
@mouseenter="$emit('preview')"
@contextmenu.prevent="$emit('rightClick')"
>
<img
:src="imageUrl"
:alt="equipment.name"
class="size-full object-contain"
loading="lazy"
decoding="async"
fetchpriority="low"
/>
<div v-if="inactive" class="absolute inset-0 bg-black/45" />
</button>
<div
v-else
class="shrink-0 rounded-sm border border-dashed border-muted-foreground/30 bg-muted/15"
:style="cellStyle"
/>
</template>