Add inline EditableField

This commit is contained in:
Girish Ramakrishnan
2025-09-11 10:11:18 +02:00
parent 3c99ccc67b
commit 14b51c0c74
2 changed files with 77 additions and 19 deletions
@@ -0,0 +1,68 @@
<script setup>
import { ref, watch, nextTick, useTemplateRef } from 'vue';
import { Button, FormGroup, TextInput } from '@cloudron/pankow';
const props = defineProps({
label: { type: String, required: true },
value: { type: String, required: true },
disabled: { type: Boolean, default: false },
saving: { type: Boolean, default: false }
});
const emit = defineEmits(['save']);
const editing = ref(false);
const draftValue = ref(props.value);
const textInput = useTemplateRef('textInput');
watch(() => props.value, (newVal) => {
if (!editing.value) draftValue.value = newVal;
});
watch(() => props.saving, (isSaving) => {
if (!isSaving && editing.value) {
editing.value = false;
}
});
function startEdit() {
if (props.disabled) return;
editing.value = true;
draftValue.value = props.value;
nextTick(() => {
textInput.value.focus();
});
}
function save() {
emit('save', draftValue.value);
}
function cancel() {
editing.value = false;
}
</script>
<template>
<FormGroup>
<label>{{ label }}</label>
<div v-if="editing" style="display: flex; gap: 6px">
<TextInput ref="textInput" v-model="draftValue" @keydown.enter="save()" :disabled="saving"/>
<Button tool @click="save" :disabled="saving">{{ $t('main.dialog.save') }}</Button>
<Button tool plain secondary @click="cancel" :disabled="saving">{{ $t('main.dialog.cancel') }}</Button>
</div>
<div v-else>
<div>{{ value }}</div>
</div>
</FormGroup>
<div>
<div v-if="editing" style="display: flex; align-items: center; gap: 10px">
</div>
<div v-else>
<Button tool plain @click="startEdit" v-if="!disabled">{{ $t('main.dialog.edit') }}</Button>
</div>
</div>
</template>