Skip to content

Documentation du composant DsfrFileUpload

🌟 Introduction

Bienvenue dans la documentation du composant DsfrFileUpload. Ce composant est l'équivalent numérique d'une balade dans les ruelles pittoresques de Montmartre, mais pour télécharger vos fichiers. Que ce soit pour des photos de vacances ou des documents importants, DsfrFileUpload rend le processus simple et élégant.

🛠️ Props

NomTypeDéfautObligatoireDescription
idFunction() => getRandomId(...)Identifiant unique pour le composant de téléchargement de fichier. Si non spécifié, un ID aléatoire est généré.
labelstring'Ajouter un fichier'Libellé pour le bouton de téléchargement de fichier.
acceptstring | string[]undefinedTypes de fichiers acceptés, spécifiés sous forme de chaîne de caractères (comme l’attribut accept de HTML) ou d'un tableau de chaînes de caractères (qui sera transformé en chaîne).
hintstring''Texte d'indice pour guider l'utilisateur.
validMessagestring''Message indiquant que le fichier téléchargé est valide.
errorstring''Message d'erreur à afficher en cas de problème lors du téléchargement.
modelValuestring''Valeur liée au modèle de l'input de téléchargement de fichier.

📡 Événements

NomDescription
update:modelValueÉvénement émis lors de la mise à jour de la valeur du modèle liée au fichier.
changeÉvénement émis lors du changement du fichier sélectionné.

📝 Exemples

Voici comment vous pourriez utiliser DsfrFileUpload :

vue
<script lang="ts" setup>
import DsfrFileUpload from '../DsfrFileUpload.vue'

const handleFileChange = (files: FileList) => {
  console.log(files) // eslint-disable-line no-console
}
</script>

<template>
  <div class="fr-container fr-my-2v">
    <DsfrFileUpload
      label="Télécharger une photo"
      hint="Formats acceptés : .jpg, .png"
      :accept="['.jpg', '.png']"
      @change="handleFileChange"
    />
    (regardez la console pour voir les fichiers sélectionnés)

    <DsfrFileUpload
      label="Télécharger une photo"
      hint="Formats acceptés : .jpg, .png"
      readonly
      accept=".pdf,.doc"
      @change="handleFileChange"
    />
    (regardez la console pour voir les fichiers sélectionnés)
  </div>
</template>

⚙️ Code source du composant

vue
<script lang="ts" setup>
import { computed } from 'vue'

import { getRandomId } from '../../utils/random-utils'

import type { DsfrFileUploadProps } from './DsfrFileUpload.types'

export type { DsfrFileUploadProps }

defineOptions({
  inheritAttrs: false,
})

const props = withDefaults(defineProps<DsfrFileUploadProps>(), {
  id: () => getRandomId('file-upload'),
  label: 'Ajouter un fichier',
  accept: undefined,
  hint: '',
  validMessage: '',
  error: '',
  modelValue: '',
})

const emit = defineEmits<{
  (e: 'update:modelValue', payload: string): void
  (e: 'change', payload: FileList): void
}>()

const onChange = ($event: InputEvent) => {
  emit('update:modelValue', ($event.target as HTMLInputElement)?.value)
  emit('change', ($event.target as (InputEvent['target'] & { files: FileList }))?.files)
}

const acceptTypes = computed(() => {
  if (Array.isArray(props.accept)) {
    return props.accept.join(',')
  }
  return props.accept
})
</script>

<template>
  <div
    class="fr-upload-group"
    :class="{
      'fr-upload-group--error': error,
      'fr-upload-group--valid': validMessage,
      'fr-upload-group--disabled': disabled,
    }"
  >
    <label
      class="fr-label"
      :for="id"
    >
      {{ label }}
      <span
        v-if="'required' in $attrs && $attrs.required !== false"
        class="required"
      >&nbsp;*</span>

      <span
        v-if="hint"
        class="fr-hint-text"
      >{{ hint }}</span>
    </label>
    <input
      :id="id"
      class="fr-upload"
      type="file"
      :aria-describedby="error || validMessage ? `${id}-desc` : undefined"
      v-bind="$attrs"
      :value="modelValue"
      :disabled="disabled"
      :aria-disabled="disabled"
      :accept="acceptTypes"
      @change="onChange($event as InputEvent)"
    >
    <div
      v-if="error || validMessage"
      class="fr-messages-group"
      role="alert"
    >
      <p
        v-if="error"
        :id="`${id}-desc`"
        class="fr-error-text  fr-mt-3v"
      >
        {{ error ?? validMessage }}
      </p>
    </div>
  </div>
</template>
ts
export type DsfrFileUploadProps = {
  id?: string
  label?: string
  accept?: string | string[]
  hint?: string
  error?: string
  validMessage?: string
  disabled?: boolean
  modelValue?: string
}