Files
spritesheet-generator/src/components/utilities/CopyToFrameModal.vue
2026-01-01 19:47:07 +01:00

73 lines
2.7 KiB
Vue

<template>
<Modal :is-open="isOpen" @close="close" title="Copy sprite to frame" :initialWidth="380" :initialHeight="320">
<div class="p-4 flex flex-col h-full">
<div class="space-y-4 flex-1">
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Target frame</label>
<select v-model.number="targetFrame" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500">
<option v-for="i in maxFrameCount" :key="i" :value="i - 1">Frame {{ i }}</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Target layer</label>
<select v-model="targetLayerId" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500">
<option v-for="layer in layers" :key="layer.id" :value="layer.id">{{ layer.name }}</option>
</select>
</div>
</div>
<div class="flex justify-end gap-3 mt-6 pt-4 border-t border-gray-100 dark:border-gray-700">
<button @click="close" class="px-4 py-2 text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors font-medium text-sm">Cancel</button>
<button @click="confirm" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium text-sm">Copy</button>
</div>
</div>
</Modal>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import Modal from './Modal.vue';
import type { Layer } from '@/types/sprites';
const props = defineProps<{
isOpen: boolean;
layers: Layer[];
initialLayerId?: string;
}>();
const emit = defineEmits<{
(e: 'close'): void;
(e: 'copy', targetLayerId: string, targetFrameIndex: number): void;
}>();
const targetFrame = ref(0);
const targetLayerId = ref('');
const maxFrameCount = computed(() => {
const maxLen = Math.max(1, ...props.layers.map(l => l.sprites.length));
return maxLen + 1; // Allow copying to one frame beyond current max
});
watch(
() => props.isOpen,
isOpen => {
if (isOpen) {
targetFrame.value = 0;
targetLayerId.value = props.initialLayerId || (props.layers.length > 0 ? props.layers[0].id : '');
}
}
);
const close = () => {
emit('close');
};
const confirm = () => {
if (targetLayerId.value) {
emit('copy', targetLayerId.value, targetFrame.value);
close();
}
};
</script>