update TextInputList with fieldset

This commit is contained in:
axolotle 2023-08-07 16:39:06 +02:00
parent ec02765545
commit 464fe40ec8
3 changed files with 64 additions and 47 deletions

View file

@ -8,6 +8,7 @@ const props = defineProps<{
icon?: string
description?: string
row?: boolean
srHideLabel?: boolean
}>()
const { errorMessage } = useField(() => props.name)
@ -38,7 +39,13 @@ provide(formGroupExtras, {
class="flex"
>
<slot name="label">
<label :id="name + '__label'" :for="name" class="block ml-1 mb-2">
<!-- eslint-disable vuejs-accessibility/label-has-for -->
<label
:id="name + '__label'"
:for="name"
class="block ms-1 mb-2"
:class="{ 'sr-only': srHideLabel }"
>
<Icon
v-if="icon"
:name="icon"

View file

@ -1,47 +1,60 @@
<script setup lang="ts">
import { useFieldArray } from 'vee-validate'
import { formGroupExtras } from '@/composables/form'
// FIXME couldn't find a way to get the index of the invalid input so for now
// every inputs are flaged as invalid
const props = defineProps<{
name: string
label: string
inputLabel: string
type: HTMLInputElement['type']
placeholder?: string
}>()
const { describedBy, invalid } = inject(formGroupExtras, {
describedBy: ref(undefined),
invalid: ref(false),
})
const group: Ref<HTMLElement | null> = ref(null)
const { remove, push, fields } = useFieldArray(props.name)
function onAdd() {
push('')
nextTick(() => {
// auto focus new input
const inputs = group.value?.querySelectorAll('input')
if (inputs && inputs.length) {
inputs[inputs.length - 1].focus()
}
})
}
</script>
<template>
<div v-for="(field, idx) in fields" :key="field.key" class="flex mb-2 join">
<input
:id="name + '__' + idx"
v-model="field.value"
:name="name"
:type="type"
:placeholder="placeholder"
:aria-invalid="invalid"
:aria-describedby="describedBy"
class="input input-bordered join-item w-full"
:class="{ 'input-error': invalid }"
/>
<fieldset ref="group">
<legend class="ms-1 mb-2">{{ label }}</legend>
<YButton
variant="error"
icon="mdi:delete-forever"
icon-size="2em"
icon-only
:text="$t('remove')"
class="join-item px-3"
@click="remove(idx)"
/>
</div>
<FormField
v-for="(field, idx) in fields"
:key="field.key"
:name="`${name}[${idx}]`"
:label="inputLabel"
class="mb-3"
sr-hide-label
>
<div class="join">
<TextInput
:name="`${name}[${idx}]`"
:type="type"
:placeholder="placeholder"
class="join-item"
/>
<YButton
variant="error"
icon="mdi:delete-forever"
icon-size="2em"
icon-only
:text="$t('remove')"
class="join-item px-3"
@click="remove(idx)"
/>
</div>
</FormField>
<YButton :text="$t('add')" @click="push('')" />
<YButton :text="$t('add')" @click="onAdd" />
</fieldset>
</template>

View file

@ -70,25 +70,22 @@ const onSubmit = handleSubmit(async (form) => {
</div>
<div class="basis-1/2 mt-10 sm:mt-0">
<FormField
<TextInputList
name="mailalias"
type="email"
:label="$t('mail_addresses')"
:input-label="$t('mail_address')"
:placeholder="$t('new_mail')"
class="mb-10"
>
<TextInputList
name="mailalias"
type="text"
:placeholder="$t('new_mail')"
/>
</FormField>
/>
<FormField name="mailforward" :label="$t('mail_forward')">
<TextInputList
name="mailforward"
type="text"
:placeholder="$t('new_forward')"
/>
</FormField>
<TextInputList
name="mailforward"
type="email"
:label="$t('mail_forwards')"
:input-label="$t('mail_forward')"
:placeholder="$t('new_forward')"
/>
</div>
</div>