This commit is contained in:
2026-06-15 01:48:03 -06:00
parent 2bd1e0399a
commit 379ff41947
40 changed files with 2669 additions and 360 deletions

View File

@@ -0,0 +1,59 @@
<script setup lang="ts">
import { nextTick, onMounted, ref, watch } from 'vue'
const props = withDefaults(
defineProps<{
modelValue: string
label: string
multiline?: boolean
editable?: boolean
}>(),
{ editable: true },
)
const emit = defineEmits<{
'update:modelValue': [value: string]
}>()
const textareaRef = ref<HTMLTextAreaElement | null>(null)
function resize(): void {
const element = textareaRef.value
if (!element) return
element.style.height = 'auto'
element.style.height = `${element.scrollHeight}px`
}
function onInput(event: Event): void {
const value = (event.target as HTMLTextAreaElement).value
emit('update:modelValue', value)
resize()
}
watch(
() => props.modelValue,
() => nextTick(resize),
)
onMounted(resize)
</script>
<template>
<textarea
v-if="editable"
ref="textareaRef"
class="editable-field editable-text"
:class="{ 'editable-text--multiline': multiline }"
:aria-label="label"
:value="modelValue"
rows="1"
@input="onInput"
></textarea>
<span
v-else
class="editable-field editable-text editable-text--static"
:class="{ 'editable-text--multiline': multiline }"
:aria-label="label"
>{{ modelValue }}</span
>
</template>