From a3743f1782f56566e1a32892340f6e6ff0f3f32e Mon Sep 17 00:00:00 2001 From: Arnaud Levy <contact@arnaudlevy.com> Date: Tue, 11 Feb 2025 08:08:16 +0100 Subject: [PATCH] test with vue inputs --- .../apps/components/inputs/InputString.vue | 67 +++++++++++++++++++ .../apps/media-picker/MediaPickerApp.vue | 17 ++--- 2 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 app/javascript/apps/components/inputs/InputString.vue diff --git a/app/javascript/apps/components/inputs/InputString.vue b/app/javascript/apps/components/inputs/InputString.vue new file mode 100644 index 000000000..8861ba8e1 --- /dev/null +++ b/app/javascript/apps/components/inputs/InputString.vue @@ -0,0 +1,67 @@ +<script> +import { Pencil } from 'lucide-vue-next'; + +export default { + props: [ + 'modelValue', + 'i18n', + 'id' + ], + emits: [ + 'update:modelValue' + ], + components: { + Pencil + }, + computed: { + value: { + get() { + return this.modelValue; + }, + set(value) { + this.$emit('update:modelValue', value); + } + } + }, + data () { + return { + editing: false + } + }, + methods: { + toggleEdition() { + this.editing = !this.editing; + if (this.editing) { + this.$nextTick(() => { + this.$refs.input.focus(); + }); + } + } + }, +}; +</script> + +<template> + <div class="mb-3"> + <label class="form-label" aria-label="{{ i18n.label }}" :for="id"> + {{ i18n.label }} + </label> + <div v-show="!editing" v-on:click="toggleEdition()"> + <p class="d-inline-block">{{ value }}</p> + <a class="btn btn-xs"> + <Pencil stroke-width="2.5" + width="18" + class="text-muted" /> + </a> + </div> + <div v-show="editing"> + <input :id="id" + class="form-control" + data-translatable="true" + v-model="value" + ref="input" + type="text"> + <div class="form-text">{{ i18n.hint }}</div> + </div> + </div> +</template> diff --git a/app/javascript/apps/media-picker/MediaPickerApp.vue b/app/javascript/apps/media-picker/MediaPickerApp.vue index 5a0a7721f..a90186365 100644 --- a/app/javascript/apps/media-picker/MediaPickerApp.vue +++ b/app/javascript/apps/media-picker/MediaPickerApp.vue @@ -4,6 +4,7 @@ import Cloud from './components/Cloud.vue'; import Medias from './components/Medias.vue'; import ImageUploader from './components/ImageUploader.vue'; import Summernote from '../components/Summernote.vue'; +import InputString from '../components/inputs/InputString.vue'; export default { components: { @@ -12,6 +13,7 @@ export default { Medias, ImageUploader, Summernote, + InputString }, data () { return { @@ -89,17 +91,10 @@ export default { {{ i18n.mediaPicker.remove }} </a> </div> - <div class="mb-3"> - <label class="form-label" aria-label="{{ i18n.mediaPicker.alt.label }}" for="alt"> - {{ i18n.mediaPicker.alt.label }} - </label> - <input id="alt" - class="form-control" - data-translatable="true" - v-model="current.image.alt" - type="text"> - <div class="form-text">{{ i18n.mediaPicker.alt.hint }}</div> - </div> + <InputString v-model="current.image.alt" + :i18n="i18n.mediaPicker.alt" + :id="'mediaPicker.alt'" + /> <div class="mb-3 summernote"> <label class="form-label" :aria-label="i18n.mediaPicker.credit.label" for="credit"> {{ i18n.mediaPicker.credit.label }} -- GitLab