Newer
Older
gnexus-tasks / frontend / src / components / QuickPrompt.vue
<script setup lang="ts">
// Модальный ввод одной строки — замена window.prompt (в стиле кита, с фокусом).
import { nextTick, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'

const props = defineProps<{ open: boolean; title: string }>()
const emit = defineEmits<{
  (e: 'update:open', value: boolean): void
  (e: 'confirm', text: string): void
}>()

const { t } = useI18n()
const text = ref('')
const inputRef = ref<HTMLInputElement | null>(null)

watch(
  () => props.open,
  (open) => {
    if (open) {
      text.value = ''
      void nextTick(() => inputRef.value?.querySelector('input')?.focus())
    }
  },
)

function submit() {
  const value = text.value.trim()
  if (!value) return
  emit('confirm', value)
  emit('update:open', false)
}
</script>

<template>
  <GnModal :open="open" :title="title" @update:open="emit('update:open', $event)">
    <form class="quick-prompt" @submit.prevent="submit">
      <GnInput ref="inputRef" v-model="text" />
      <div class="quick-prompt-actions">
        <GnButton type="submit" variant="primary" icon="ph-check">
          {{ t('common.save') }}
        </GnButton>
        <GnButton type="button" variant="secondary" @click="emit('update:open', false)">
          {{ t('common.cancel') }}
        </GnButton>
      </div>
    </form>
  </GnModal>
</template>

<style scoped>
.quick-prompt {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}
.quick-prompt-actions {
  display: flex;
  gap: 0.75rem;
}
</style>