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 icon?: string
description?: string description?: string
row?: boolean row?: boolean
srHideLabel?: boolean
}>() }>()
const { errorMessage } = useField(() => props.name) const { errorMessage } = useField(() => props.name)
@ -38,7 +39,13 @@ provide(formGroupExtras, {
class="flex" class="flex"
> >
<slot name="label"> <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 <Icon
v-if="icon" v-if="icon"
:name="icon" :name="icon"

View file

@ -1,37 +1,48 @@
<script setup lang="ts"> <script setup lang="ts">
import { useFieldArray } from 'vee-validate' 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<{ const props = defineProps<{
name: string name: string
label: string
inputLabel: string
type: HTMLInputElement['type'] type: HTMLInputElement['type']
placeholder?: string placeholder?: string
}>() }>()
const { describedBy, invalid } = inject(formGroupExtras, { const group: Ref<HTMLElement | null> = ref(null)
describedBy: ref(undefined),
invalid: ref(false),
})
const { remove, push, fields } = useFieldArray(props.name) 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> </script>
<template> <template>
<div v-for="(field, idx) in fields" :key="field.key" class="flex mb-2 join"> <fieldset ref="group">
<input <legend class="ms-1 mb-2">{{ label }}</legend>
:id="name + '__' + idx"
v-model="field.value" <FormField
:name="name" 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" :type="type"
:placeholder="placeholder" :placeholder="placeholder"
:aria-invalid="invalid" class="join-item"
:aria-describedby="describedBy"
class="input input-bordered join-item w-full"
:class="{ 'input-error': invalid }"
/> />
<YButton <YButton
variant="error" variant="error"
icon="mdi:delete-forever" icon="mdi:delete-forever"
@ -42,6 +53,8 @@ const { remove, push, fields } = useFieldArray(props.name)
@click="remove(idx)" @click="remove(idx)"
/> />
</div> </div>
</FormField>
<YButton :text="$t('add')" @click="push('')" /> <YButton :text="$t('add')" @click="onAdd" />
</fieldset>
</template> </template>

View file

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