Files
hms-licht-ton/frontend/components/SpeakerIcon.vue
T

91 lines
3.7 KiB
Vue
Raw Normal View History

<template>
<div
class="flex flex-col items-center gap-2 p-4 rounded-lg border border-border-default bg-panel hover:border-accent-border transition-colors duration-fast cursor-pointer group"
role="button"
:tabindex="0"
:aria-label="type"
@click="$emit('select', type)"
@keydown.enter="$emit('select', type)"
>
<svg
:width="size"
:height="size"
viewBox="0 0 48 48"
fill="none"
class="text-secondary group-hover:text-accent transition-colors duration-fast"
aria-hidden="true"
>
<!-- Line Array -->
<template v-if="type === 'line-array'">
<rect x="6" y="16" width="8" height="16" rx="1" fill="currentColor" />
<path d="M16 20 L24 14 M16 28 L24 34" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
<path d="M26 12 L30 10 M26 36 L30 38" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.6" />
<path d="M32 8 L36 6 M32 40 L36 42" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.3" />
</template>
<!-- Subwoofer -->
<template v-else-if="type === 'subwoofer'">
<rect x="8" y="8" width="32" height="32" rx="2" fill="none" stroke="currentColor" stroke-width="2" />
<circle cx="24" cy="24" r="8" fill="none" stroke="currentColor" stroke-width="2" />
<circle cx="24" cy="24" r="4" fill="none" stroke="currentColor" stroke-width="1.5" />
</template>
<!-- Point Source -->
<template v-else-if="type === 'point-source'">
<rect x="10" y="18" width="10" height="12" rx="1" fill="currentColor" />
<path d="M22 16 Q28 24 22 32" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
<path d="M26 12 Q34 24 26 36" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.6" />
</template>
<!-- Column Array -->
<template v-else-if="type === 'column-array'">
<rect x="16" y="6" width="16" height="36" rx="1" fill="none" stroke="currentColor" stroke-width="2" />
<circle cx="24" cy="14" r="3" fill="currentColor" />
<circle cx="24" cy="24" r="3" fill="currentColor" />
<circle cx="24" cy="34" r="3" fill="currentColor" />
</template>
<!-- Monitor -->
<template v-else-if="type === 'monitor'">
<path d="M6 30 L24 14 L42 30 L42 34 L6 34 Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
<circle cx="24" cy="26" r="4" fill="none" stroke="currentColor" stroke-width="1.5" />
</template>
<!-- Moving Head -->
<template v-else>
<rect x="18" y="6" width="12" height="10" rx="1" fill="currentColor" />
<path d="M24 16 L24 24" stroke="currentColor" stroke-width="2" stroke-linecap="round" />
<circle cx="24" cy="30" r="6" fill="none" stroke="currentColor" stroke-width="2" />
<path d="M18 30 L14 30 M30 30 L34 30" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" opacity="0.5" />
</template>
</svg>
<span class="text-xs text-text-muted group-hover:text-accent transition-colors duration-fast">{{ label }}</span>
</div>
</template>
<script setup lang="ts">
const props = withDefaults(defineProps<{
type: "line-array" | "subwoofer" | "point-source" | "column-array" | "monitor" | "moving-head";
label?: string;
size?: number;
}>(), {
label: "",
size: 48,
});
const labelMap: Record<string, string> = {
"line-array": "Line Array",
"subwoofer": "Subwoofer",
"point-source": "Point Source",
"column-array": "Column Array",
"monitor": "Monitor",
"moving-head": "Moving Head",
};
const label = computed(() => props.label || labelMap[props.type] || props.type);
defineEmits<{
select: [type: string];
}>();
</script>