{# # ============================================================================ # MOLECULE: FORM-FIELD # ============================================================================ # # Champ de formulaire complet combinant Label + Input + Messages. # Molécule réutilisable pour tous les formulaires de l'application. # Supporte aussi type: file avec mode dropzone. # # ============================================================================ # COMPOSITION (Atomes utilisés) # ============================================================================ # # - _atoms/form/label.html.twig # - _atoms/form/input.html.twig (ou textarea) # - _atoms/icon/icon.html.twig # # ============================================================================ # PARAMÈTRES # ============================================================================ # # | Paramètre | Type | Défaut | Description | # |----------------|---------|-----------|------------------------------------------| # | name | string | (requis) | Nom du champ (id auto-généré) | # | label | string | null | Texte du label | # | type | string | 'text' | Type: text, email, password, textarea, file | # | placeholder | string | '' | Placeholder | # | value | string | '' | Valeur du champ | # | required | bool | false | Champ obligatoire | # | disabled | bool | false | Champ désactivé | # | error | string | null | Message d'erreur | # | hint | string | null | Texte d'aide | # | icon | string | null | Nom de l'icône (left par défaut) | # | iconPosition | string | 'left' | Position: left, right | # | size | string | 'md' | Taille: sm, md, lg | # | variant | string | 'default' | Style: default, filled | # | labelTooltip | string | null | Tooltip sur le label | # | rows | number | 4 | Lignes pour textarea | # | optional | bool | false | Affiche "(optionnel)" sur le label | # | srOnly | bool | false | Label visible uniquement pour lecteurs | # | class | string | '' | Classes additionnelles sur le wrapper | # | inputClass | string | '' | Classes additionnelles sur l'input | # | attr | object | {} | Attributs HTML additionnels | # | | | | | # | --- TYPE FILE SPECIFIQUE --- | # | accept | string | null | Types acceptés (ex: '.pdf,.doc') | # | multiple | bool | false | Autoriser plusieurs fichiers | # | maxSize | string | null | Taille max affichée (ex: '20 MB') | # | dropzone | bool | false | Mode drag & drop | # | dropzoneText | string | 'Glissez...'| Texte principal dropzone | # | dropzoneHint | string | null | Texte secondaire dropzone | # # ============================================================================ # EXEMPLES D'UTILISATION # ============================================================================ # # Champ email simple: # {% include '_molecules/form/form-field.html.twig' with { # name: 'email', # label: 'Adresse email', # type: 'email', # placeholder: 'votre@email.com', # required: true # } %} # # Champ mot de passe avec erreur: # {% include '_molecules/form/form-field.html.twig' with { # name: 'password', # label: 'Mot de passe', # type: 'password', # icon: 'lock', # required: true, # error: 'Le mot de passe est incorrect' # } %} # # File upload simple: # {% include '_molecules/form/form-field.html.twig' with { # name: 'document', # label: 'Document', # type: 'file', # accept: '.pdf,.doc,.docx', # hint: 'PDF ou Word, max 20 MB' # } %} # # File upload avec dropzone: # {% include '_molecules/form/form-field.html.twig' with { # name: 'files', # label: 'Fichiers', # type: 'file', # dropzone: true, # multiple: true, # accept: '.pdf,.pptx', # maxSize: '20 MB', # dropzoneText: 'Glissez vos fichiers ici', # dropzoneHint: 'ou cliquez pour parcourir' # } %} # # Textarea: # {% include '_molecules/form/form-field.html.twig' with { # name: 'description', # label: 'Description', # type: 'textarea', # rows: 6, # hint: 'Maximum 500 caractères' # } %} # # ============================================================================ #} {# ============================================================================ CONFIGURATION DES VALEURS PAR DÉFAUT ============================================================================ #} {% set name = name ?? '' %} {% set label = label ?? null %} {% set type = type ?? 'text' %} {% set placeholder = placeholder ?? '' %} {% set value = value ?? '' %} {% set required = required ?? false %} {% set disabled = disabled ?? false %} {% set error = error ?? null %} {% set hint = hint ?? null %} {% set icon = icon ?? null %} {% set iconPosition = iconPosition ?? 'left' %} {% set size = size ?? 'md' %} {% set variant = variant ?? 'default' %} {% set labelTooltip = labelTooltip ?? null %} {% set rows = rows ?? 4 %} {% set optional = optional ?? false %} {% set srOnly = srOnly ?? false %} {% set class = class ?? '' %} {% set inputClass = inputClass ?? '' %} {% set attr = attr ?? {} %} {# File specific parameters #} {% set accept = accept ?? null %} {% set multiple = multiple ?? false %} {% set maxSize = maxSize ?? null %} {% set dropzone = dropzone ?? false %} {% set dropzoneText = dropzoneText ?? 'Glissez vos fichiers ici' %} {% set dropzoneHint = dropzoneHint ?? 'ou cliquez pour parcourir' %} {# ID auto-généré #} {% set fieldId = 'field-' ~ name %} {% set isFileType = type == 'file' %} {# ============================================================================ RENDU HTML ============================================================================ #}
{{ dropzoneText }}
{{ dropzoneHint }}
{% if accept or maxSize %}{% if accept %}{{ accept|replace({'.': '', ',': ', '}) }}{% endif %} {% if accept and maxSize %} • {% endif %} {% if maxSize %}Max {{ maxSize }}{% endif %}
{% endif %}{{ hint }}
{% endif %} {# ----- Error message ----- #} {% if error %}{% include '_atoms/icon/icon.html.twig' with { name: 'alert', size: 'xs' } only %} {{ error }}
{% endif %}