# Guide des Composants Composites Freya Extension

## Vue d'ensemble

L'extension Freya fournit 15 composants composites qui appliquent automatiquement les patterns Freya et réduisent le code boilerplate dans vos formulaires Jakarta Faces.

### Namespace

```xml
xmlns:fr="http://primefaces.org/freya"
```

### Avantages

✅ **Réduction massive du boilerplate** - ~80% de code en moins
✅ **Pattern Freya garanti** - Structure `field` et `field-checkbox` standardisée
✅ **Indicateur requis optimal** - Astérisque rouge géré proprement via `h:outputText`
✅ **Composants modernes** - Utilisation de `p:datePicker`, `p:toggleSwitch`, etc.
✅ **Fluid Design** - Tous les champs sont optimisés pour `ui-fluid`
✅ **Validation simplifiée** - Un seul tag pour label + input + message

---

## Liste des Composants

| Catégorie | Composant | Description | PF Natif |
|-----------|-----------|-------------|----------|
| **Texte** | `fr:fieldInput` | Champ texte standard | `p:inputText` |
| | `fr:fieldTextarea` | Zone de texte multiligne | `p:inputTextarea` |
| | `fr:fieldPassword` | Mot de passe | `p:password` |
| | `fr:fieldChips` | Saisie de tags | `p:chips` |
| **Sélection** | `fr:fieldSelect` | Liste déroulante unique | `p:selectOneMenu` |
| | `fr:fieldMultiSelect`| Liste déroulante multiple | `p:selectCheckboxMenu`|
| | `fr:fieldRadio` | Boutons radio | `p:selectOneRadio` |
| **Date & Nombre**| `fr:fieldCalendar` | Sélecteur de date | `p:datePicker` |
| | `fr:fieldNumber` | Champ numérique | `p:inputNumber` |
| **Boutons** | `fr:fieldCheckbox` | Case à cocher | `p:selectBooleanCheckbox`|
| | `fr:fieldSwitch` | Interrupteur | `p:toggleSwitch` |
| | `fr:fieldToggle` | Bouton bascule | `p:selectBooleanButton` |
| **Spéciaux** | `fr:fieldRating` | Évaluation | `p:rating` |
| | `fr:fieldColor` | Couleur | `p:colorPicker` |
| **Layout** | `fr:actionDialog` | Dialog standardisé | `p:dialog` |

---

## Détails des Composants

### 1. fr:fieldInput
*(Identique à la version précédente)*

### 2. fr:fieldNumber
Champ numérique pour les montants, prix ou quantités.

#### Attributs spécifiques
| Attribut | Type | Défaut | Description |
|----------|------|--------|-------------|
| `symbol` | String | - | Symbole monétaire (ex: " FCFA") |
| `symbolPosition`| String | "p" | Position du symbole ("p"refix, "s"uffix) |
| `decimalPlaces` | String | "2" | Nombre de décimales |
| `minValue` | String | - | Valeur minimale |
| `maxValue` | String | - | Valeur maximale |

### 3. fr:fieldSelect
*(Identique à la version précédente)*

### 4. fr:fieldMultiSelect
Sélecteur multiple compact.

#### Attributs spécifiques
| Attribut | Type | Défaut | Description |
|----------|------|--------|-------------|
| `filter` | Boolean | `false` | Active la recherche |
| `multiple` | Boolean | `true` | Sélection multiple |

### 5. fr:fieldRadio
Boutons radio pour un choix exclusif visible.

#### Attributs spécifiques
| Attribut | Type | Défaut | Description |
|----------|------|--------|-------------|
| `layout` | String | "lineDirection"| Disposition ("lineDirection" ou "pageDirection") |

### 6. fr:fieldCalendar
Sélecteur de date moderne (DatePicker).

#### Attributs spécifiques
| Attribut | Type | Défaut | Description |
|----------|------|--------|-------------|
| `showIcon` | Boolean | `true` | Affiche l'icône calendrier |
| `pattern` | String | - | Format (ex: "dd/MM/yyyy") |
| `yearRange` | String | - | Plage d'années |

### 7. fr:fieldPassword
*(Identique à la version précédente)*

### 8. fr:fieldTextarea
*(Identique à la version précédente)*

### 9. fr:fieldCheckbox
Case à cocher standard. Utilise le layout `field-checkbox`.

### 10. fr:fieldSwitch
Interrupteur ON/OFF moderne.

### 11. fr:fieldToggle
Bouton avec états ON/OFF personnalisables.

#### Attributs spécifiques
| Attribut | Type | Défaut | Description |
|----------|------|--------|-------------|
| `onLabel` | String | "Oui" | Texte état ON |
| `offLabel` | String | "Non" | Texte état OFF |
| `onIcon` | String | - | Icône état ON |
| `offIcon` | String | - | Icône état OFF |

### 12. fr:fieldChips
Saisie de tags/mots-clés.

### 13. fr:fieldRating
Saisie d'une note.

### 14. fr:fieldColor
Sélecteur de couleur graphique.

### 15. fr:actionDialog
*(Identique à la version précédente)*

**Dialog personnalisé:**
```xml
<fr:actionDialog widgetVar="dlgConfirmDelete"
                header="Confirmer la suppression"
                width="400px"
                cancelLabel="Non"
                confirmLabel="Oui, supprimer"
                confirmIcon="pi pi-trash"
                confirmAction="#{userBean.deleteUser}"
                confirmUpdate="userTable">
    <p>Êtes-vous sûr de vouloir supprimer cet utilisateur ?</p>
    <p><strong>#{userBean.selectedUser.nom}</strong></p>
</fr:actionDialog>
```

**Ouverture/fermeture:**
```xml
<!-- Bouton pour ouvrir -->
<p:commandButton value="Éditer"
                 icon="pi pi-pencil"
                 onclick="PF('dlgEditUser').show()"
                 update="dlgEditUser" />

<!-- Le dialog se ferme automatiquement si la validation réussit -->
<!-- Ou fermeture manuelle en JavaScript: PF('dlgEditUser').hide() -->
```

**Comportement:**
- Le bouton **Annuler** ferme le dialog sans exécuter d'action
- Le bouton **Sauvegarder** exécute l'action et ferme le dialog **uniquement si la validation réussit**
- Le contenu du dialog utilise `ui-fluid` pour des inputs pleine largeur

---

## Formulaire complet - Exemple

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:fr="http://primefaces.org/freya">

<h:head>
    <title>Inscription utilisateur</title>
</h:head>

<h:body>
    <div class="grid">
        <div class="col-12 md:col-8 md:col-offset-2">
            <div class="card">
                <h3>Créer un compte</h3>

                <h:form id="registerForm">
                    <div class="grid">
                        <div class="col-12 md:col-6">
                            <fr:fieldInput label="Prénom"
                                         value="#{registerBean.user.prenom}"
                                         required="true" />
                        </div>
                        <div class="col-12 md:col-6">
                            <fr:fieldInput label="Nom"
                                         value="#{registerBean.user.nom}"
                                         required="true" />
                        </div>
                    </div>

                    <fr:fieldInput label="Email"
                                 value="#{registerBean.user.email}"
                                 required="true" />

                    <fr:fieldPassword label="Mot de passe"
                                    value="#{registerBean.user.password}"
                                    feedback="true"
                                    required="true" />

                    <fr:fieldPassword label="Confirmer le mot de passe"
                                    value="#{registerBean.passwordConfirm}"
                                    feedback="false"
                                    required="true" />

                    <fr:fieldCalendar label="Date de naissance"
                                    value="#{registerBean.user.dateNaissance}"
                                    yearRange="1940:2010"
                                    required="true" />

                    <fr:fieldSelect label="Pays"
                                  value="#{registerBean.user.pays}"
                                  filter="true"
                                  required="true">
                        <f:selectItem itemLabel="-- Sélectionnez --" itemValue="" />
                        <f:selectItems value="#{referentielBean.paysList}" />
                    </fr:fieldSelect>

                    <fr:fieldTextarea label="Présentation (optionnel)"
                                    value="#{registerBean.user.bio}"
                                    rows="4"
                                    maxlength="500" />

                    <fr:fieldCheckbox label="J'accepte les conditions d'utilisation"
                                    value="#{registerBean.acceptTerms}"
                                    required="true" />

                    <fr:fieldCheckbox label="Je souhaite recevoir la newsletter"
                                    value="#{registerBean.user.newsletter}" />

                    <div class="field" style="margin-top: 1.5rem;">
                        <p:commandButton value="S'inscrire"
                                       icon="pi pi-user-plus"
                                       action="#{registerBean.register}"
                                       update="registerForm"
                                       styleClass="ui-button-success" />

                        <p:commandButton value="Annuler"
                                       icon="pi pi-times"
                                       action="#{registerBean.cancel}"
                                       styleClass="ui-button-secondary"
                                       style="margin-left: 0.5rem;" />
                    </div>
                </h:form>
            </div>
        </div>
    </div>
</h:body>
</html>
```

---

## Comparaison Avant/Après

### Sans l'extension (PrimeFaces standard)

```xml
<div class="field">
    <p:outputLabel for="nom" value="Nom">
        <span class="p-error"> *</span>
    </p:outputLabel>
    <p:inputText id="nom" value="#{bean.nom}" required="true" />
    <p:message for="nom" />
</div>

<div class="field">
    <p:outputLabel for="prenom" value="Prénom">
        <span class="p-error"> *</span>
    </p:outputLabel>
    <p:inputText id="prenom" value="#{bean.prenom}" required="true" />
    <p:message for="prenom" />
</div>
```

**10 lignes de code**

### Avec l'extension (Freya composites)

```xml
<fr:fieldInput label="Nom" value="#{bean.nom}" required="true" />
<fr:fieldInput label="Prénom" value="#{bean.prenom}" required="true" />
```

**2 lignes de code** ✅

### Réduction

- **80% moins de code**
- **Même résultat visuel**
- **Même fonctionnalité**
- **Pattern Freya garanti**

---

## Intégration avec Validation Bean

Les composants supportent pleinement Bean Validation (Jakarta Validation):

```java
public class User {
    @NotBlank(message = "Le nom est obligatoire")
    @Size(min = 2, max = 50, message = "Le nom doit contenir entre 2 et 50 caractères")
    private String nom;

    @Email(message = "Email invalide")
    @NotBlank(message = "L'email est obligatoire")
    private String email;

    @Past(message = "La date de naissance doit être dans le passé")
    private LocalDate dateNaissance;
}
```

```xml
<fr:fieldInput label="Nom" value="#{userBean.user.nom}" required="true" />
<fr:fieldInput label="Email" value="#{userBean.user.email}" required="true" />
<fr:fieldCalendar label="Date de naissance" value="#{userBean.user.dateNaissance}" required="true" />
```

Les messages de validation Bean Validation s'afficheront automatiquement via `<p:message>`.

---

## Personnalisation

### Classes CSS additionnelles

```xml
<fr:fieldInput label="Code VIP"
               value="#{bean.codeVip}"
               styleClass="highlight-field" />
```

Génère:
```xml
<div class="field highlight-field">
    ...
</div>
```

### Binding de composants

Pour accéder au composant PrimeFaces sous-jacent:

```xml
<fr:fieldInput label="Nom"
               value="#{bean.nom}"
               binding="#{bean.nomInput}" />
```

Dans le bean:
```java
private InputText nomInput; // PrimeFaces component

public void someMethod() {
    nomInput.setDisabled(true);
}
```

---

## Bonnes pratiques

✅ **DO:**
- Utiliser `fr:field*` pour tous les champs de formulaire
- Utiliser `fr:actionDialog` pour les dialogs CRUD standard
- Combiner avec les grids PrimeFlex (`grid`, `col-*`)
- Grouper les champs connexes dans `<div class="card">`

❌ **DON'T:**
- Ne pas imbriquer les composants `fr:field*` (ils créent déjà un `<div class="field">`)
- Ne pas dupliquer les labels (le composant gère déjà le label)
- Ne pas oublier `widgetVar` sur `fr:actionDialog` (obligatoire)

---

## Technologies

- **Jakarta Faces 4.0** (Composite Components)
- **PrimeFaces 14.0.0** (Jakarta)
- **Freya Theme 5.0.0**
- **PrimeFlex 3.3.1** (Grid système)

---

## Support

Pour plus d'informations:
- [PrimeFaces Documentation](https://primefaces.github.io/primefaces/)
- [Freya Theme](https://freya.primefaces.org/)
- [Jakarta Faces Composite Components](https://jakarta.ee/learn/docs/jakartaee-tutorial/current/web/faces-advanced-cc/faces-advanced-cc.html)
