Skip to content

useFormField ​

Relie un contrôle au SuFormField qui l'entoure : id (cible du label), label, message d'aide et états du champ. Les contrôles SurgeUI l'utilisent déjà ; ce composable sert à vos propres contrôles.

Sans rien à faire ​

Un contrôle SurgeUI placé dans le slot d'un SuFormField est relié automatiquement, sans slotProps :

vue
<SuFormField label="E-mail" message="Adresse professionnelle" state="error" required>
  <SuInput v-model="email" type="email" />
</SuFormField>

Rendu : <label for> cible l'input, aria-describedby pointe vers le message, aria-invalid et aria-required sont posés, l'état d'erreur et la taille sont hérités.

Dans un contrôle maison ​

vue
<!-- ColorField.vue -->
<script setup lang="ts">
import { useFormField } from '@surgeui/ds-vue'

const props = withDefaults(defineProps<{
  state?: 'default' | 'error' | 'success' | 'warning'
  size?: 'sm' | 'md' | 'lg'
  disabled?: boolean
  required?: boolean
}>(), { state: 'default', size: 'md' })

const model = defineModel<string>()

const { id, state, disabled, required, describedBy } = useFormField(props, {
  idPrefix: 'color'
})
</script>

<template>
  <input
    :id="id"
    v-model="model"
    type="color"
    :disabled="disabled"
    :aria-required="required || undefined"
    :aria-invalid="state === 'error' || undefined"
    :aria-describedby="describedBy"
  >
</template>
vue
<SuFormField label="Couleur principale" message="Utilisée pour les boutons">
  <ColorField v-model="color" />
</SuFormField>

Contrôle non ciblable par un label ​

Un <label for> ne cible que les éléments natifs (input, select, textarea, button). Pour un contrôle construit avec un div (combobox, groupe, curseur), déclarez-le non ciblable : il reçoit alors aria-labelledby vers le label, et le clic sur le label lui donne le focus.

ts
const rootRef = ref<HTMLElement>()

const { labelledBy } = useFormField(props, {
  labelable: false,
  focus: () => rootRef.value?.focus()
})

Priorités ​

ValeurRègle
idattribut id du contrôle, sinon celui du champ, sinon généré (idPrefix)
state, sizevaleur du contrôle si elle diffère du défaut (default, md), sinon celle du champ
disabled, requiredvrai si le contrôle ou le champ l'est
describedByaria-describedby du contrôle + message du champ, sans doublon
labelledByaria-labelledby du contrôle, sinon le label du champ (contrôle non ciblable)

Un champ relie un seul contrôle : pour plusieurs contrôles, utilisez FormFieldGroup.

API ​

ts
useFormField(props, options?)

Options ​

OptionTypeDéfautDescription
labelablebooleantrueLe contrôle est ciblable par <label for>
focus() => void—Donne le focus au contrôle (clic sur le label d'un contrôle non ciblable)
idPrefixstring—Préfixe de l'id généré hors champ ; sans préfixe, aucun id n'est généré

Retour ​

PropriétéTypeDescription
fieldFormFieldContext | nullContexte du champ, ou null hors SuFormField
idComputedRef<string | undefined>Id du contrôle
stateComputedRef<State>État effectif
sizeComputedRef<Size>Taille effective
disabledComputedRef<boolean>Désactivé
requiredComputedRef<boolean>Requis
describedByComputedRef<string | undefined>Valeur d'aria-describedby
labelledByComputedRef<string | undefined>Valeur d'aria-labelledby

Autres exports ​

ExportDescription
mergeIds(...ids)Joint des listes d'ids sans doublons ni vides
provideFormField(context) / FormFieldKeyFournir le contexte depuis votre propre composant de champ

Publié sous licence MIT.