funkwhale/front/src/components/forms/PasswordInput.vue

77 lines
1.7 KiB
Vue

<script setup lang="ts">
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useClipboard, useVModel } from '@vueuse/core'
import { useStore } from '~/store'
import Button from '~/components/ui/Button.vue'
import Input from '~/components/ui/Input.vue'
interface Events {
(e: 'update:modelValue', value: string): void
}
interface Props {
modelValue: string
defaultShow?: boolean
copyButton?: boolean
fieldId: string
}
const emit = defineEmits<Events>()
const props = withDefaults(defineProps<Props>(), {
defaultShow: false,
copyButton: false
})
const value = useVModel(props, 'modelValue', emit)
const showPassword = ref(props.defaultShow)
const { t } = useI18n()
const labels = computed(() => ({
title: t('components.forms.PasswordInput.title'),
copy: t('components.forms.PasswordInput.button.copy')
}))
const passwordInputType = computed(() => showPassword.value ? 'text' : 'password')
const store = useStore()
const { isSupported: canCopy, copy } = useClipboard({ source: value })
const copyPassword = () => {
copy()
store.commit('ui/addMessage', {
content: t('components.forms.PasswordInput.message.copy'),
date: new Date()
})
}
</script>
<template>
<div>
<Input
:id="fieldId"
v-model="value"
required
name="password"
:type="passwordInputType"
>
<template #input-right>
<Button
:title="labels.title"
icon="bi-eye"
@click.prevent="showPassword = !showPassword"
>
</Button>
<Button
v-if="copyButton && canCopy"
icon="bi-copy"
:title="labels.copy"
@click.prevent="copyPassword"
>
</Button>
</template>
</Input>
</div>
</template>