# PrimeFaces Freya Extension

Extension Quarkus fournissant **43 composants composites** optimisés pour simplifier l'utilisation de PrimeFaces avec le thème **Freya**.

---

## 🎯 Philosophie

Cette extension suit une approche **complète et moderne** :

- ✅ **43 composants prêts à l'emploi** : Formulaires, données, navigation, feedback, layout, etc.
- ✅ **PrimeFaces standard** : Utilise les composants PrimeFaces natifs sous le capot
- ✅ **Réduction du boilerplate** : ~80% moins de code pour les formulaires
- ✅ **Pattern Freya automatique** : Structure `field` appliquée systématiquement
- ✅ **100% Compatible** : Fonctionne avec tout projet Quarkus + PrimeFaces
- ✅ **Optimal** : Correction des bugs d'accessibilité et d'affichage (indicateurs requis)
- ✅ **Design moderne** : Interface responsive avec Tailwind CSS intégré

> **Note importante** : Freya est un **thème**, pas une bibliothèque de composants. Il fournit uniquement FreyaMenu (Java) et des classes CSS. Cette extension ajoute 43 composants composites pour simplifier l'usage des patterns Freya.

---

## 📦 Installation

### Dans un Projet Quarkus

Ajoutez la dépendance dans votre `pom.xml` :

```xml
<dependency>
    <groupId>dev.lions</groupId>
    <artifactId>primefaces-freya-extension</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>
```

### Configuration

Dans `application.properties` :

```properties
# PrimeFaces Configuration
primefaces.THEME=freya
primefaces.FONT_AWESOME=true
primefaces.CLIENT_SIDE_VALIDATION=true
primefaces.MOVE_SCRIPTS_TO_BOTTOM=true
```

---

## 🚀 Utilisation Rapide

### 1. Déclarer le Namespace

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

### 2. Utiliser les Composants

**Avant (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>
```

**Après (Freya Extension) :**
```xml
<fr:fieldInput label="Nom" value="#{bean.nom}" required="true" />
```

**Résultat : 80% moins de code, même fonctionnalité**

---

## 🎨 Composants Disponibles (43 au total)

### Formulaires (15 composants)
| Composant | Description | Composant PF sous-jacent |
|-----------|-------------|--------------------------|
| `fr:fieldInput` | Champ texte simple | `p:inputText` |
| `fr:fieldSelect` | Liste déroulante unique | `p:selectOneMenu` |
| `fr:fieldCheckbox` | Case à cocher unique | `p:selectBooleanCheckbox` |
| `fr:fieldRadio` | Boutons radio | `p:selectOneRadio` |
| `fr:fieldTextarea` | Zone de texte multiligne | `p:inputTextarea` |
| `fr:fieldCalendar` | Sélecteur de date | `p:datePicker` |
| `fr:fieldPassword` | Mot de passe sécurisé | `p:password` |
| `fr:fieldChips` | Saisie de tags | `p:chips` |
| `fr:fieldColorPicker` | Sélecteur de couleur | `p:colorPicker` |
| `fr:fieldRating` | Évaluation par étoiles | `p:rating` |
| `fr:fieldToggleSwitch` | Interrupteur ON/OFF | `p:toggleSwitch` |
| `fr:fieldMask` | Champ avec masque de saisie | `p:inputMask` |
| `fr:fieldSpinner` | Sélecteur numérique | `p:spinner` |
| `fr:fieldSlider` | Curseur de valeur | `p:slider` |
| `fr:fieldAutoComplete` | Autocomplétion | `p:autoComplete` |

### Données (1 composant)
| Composant | Description | Composant PF sous-jacent |
|-----------|-------------|--------------------------|
| `fr:dataTable` | Tableau de données avec pagination | `p:dataTable` |

### Navigation (3 composants)
| Composant | Description | Composant PF sous-jacent |
|-----------|-------------|--------------------------|
| `fr:breadcrumb` | Fil d'Ariane | `p:breadCrumb` |
| `fr:steps` | Indicateur d'étapes | `p:steps` |
| `fr:tabView` | Onglets | `p:tabView` |

### Actions (4 composants)
| Composant | Description | Composant PF sous-jacent |
|-----------|-------------|--------------------------|
| `fr:button` | Bouton simple | `p:button` |
| `fr:commandButton` | Bouton avec action | `p:commandButton` |
| `fr:linkButton` | Bouton lien | `p:linkButton` |
| `fr:splitButton` | Bouton avec menu | `p:splitButton` |

### Feedback (3 composants)
| Composant | Description | Composant PF sous-jacent |
|-----------|-------------|--------------------------|
| `fr:message` | Message de validation | `p:message` |
| `fr:inplace` | Édition en place | `p:inplace` |
| `fr:growl` | Notifications toast | `p:growl` |

### Utilitaires (6 composants)
| Composant | Description | Composant PF sous-jacent |
|-----------|-------------|--------------------------|
| `fr:avatar` | Avatar utilisateur | `p:avatar` |
| `fr:badge` | Badge de notification | `p:badge` |
| `fr:tag` | Étiquette | `p:tag` |
| `fr:divider` | Séparateur | `p:divider` |
| `fr:progressBar` | Barre de progression | `p:progressBar` |
| `fr:spacer` | Espacement | `p:spacer` |

### Layout (2 composants)
| Composant | Description | Composant PF sous-jacent |
|-----------|-------------|--------------------------|
| `fr:card` | Carte de contenu | `p:panel` |
| `fr:panel` | Panneau pliable | `p:panel` |

### Dialogs (2 composants)
| Composant | Description | Composant PF sous-jacent |
|-----------|-------------|--------------------------|
| `fr:actionDialog` | Dialog avec actions | `p:dialog` |
| `fr:formDialog` | Dialog avec formulaire | `p:dialog` |

---

## 📖 Exemples

### Formulaire d'Inscription

```xml
<h:form id="registerForm">
    <div class="card">
        <h3>Créer un compte</h3>

        <fr:fieldInput label="Prénom"
                     value="#{registerBean.user.prenom}"
                     required="true" />

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

        <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: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" />

        <p:commandButton value="S'inscrire"
                       icon="pi pi-user-plus"
                       action="#{registerBean.register}"
                       update="registerForm"
                       styleClass="ui-button-success" />
    </div>
</h:form>
```

### Dialog CRUD

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

<!-- Dialog avec formulaire -->
<fr:actionDialog widgetVar="dlgEditUser"
                header="Modifier l'utilisateur"
                confirmAction="#{userBean.saveUser}"
                confirmUpdate="userTable">
    <fr:fieldInput label="Nom"
                 value="#{userBean.selectedUser.nom}"
                 required="true" />

    <fr:fieldInput label="Prénom"
                 value="#{userBean.selectedUser.prenom}"
                 required="true" />

    <fr:fieldSelect label="Rôle"
                  value="#{userBean.selectedUser.role}"
                  required="true">
        <f:selectItem itemLabel="-- Choisir --" itemValue="" />
        <f:selectItems value="#{userBean.rolesList}" />
    </fr:fieldSelect>
</fr:actionDialog>
```

---

## 📚 Documentation Complète

### Guides principaux

📖 **[Guide de Démarrage Rapide](QUICKSTART.md)** ⚡
- Installation en 5 minutes
- Premier formulaire
- Exemples de code complets

📖 **[Guide Complet des Composants](COMPOSANTS_GUIDE.md)**
- Tous les attributs disponibles pour chaque composant
- Exemples d'usage pour chaque cas d'usage
- Intégration avec Bean Validation
- Bonnes pratiques
- Comparaison avant/après

📖 **[Guide d'Accessibilité](ACCESSIBILITY.md)** ♿
- Standards WCAG 2.1
- Navigation au clavier
- Support des lecteurs d'écran
- Bonnes pratiques d'accessibilité

📖 **[Guide de Contribution](CONTRIBUTING.md)** 🤝
- Comment contribuer
- Standards de code
- Processus de Pull Request
- Créer un nouveau composant

📖 **[Changelog](CHANGELOG.md)** 📝
- Historique des versions
- Nouvelles fonctionnalités
- Corrections de bugs
- Roadmap

### Guides techniques

📖 **[Analyse Officielle Freya](ANALYSE_OFFICIELLE.md)**
- Découverte importante : Freya fournit uniquement 1 composant Java (FreyaMenu), le reste est du CSS

📖 **[Guide d'Usage Freya](FREYA_USAGE_GUIDE.md)**
- Exemples tirés des sources officielles Freya 5.0.0

---

## 🧪 Démonstration

Une page de démonstration complète est disponible :

**Fichier** : `demo/components-demo.xhtml`
**Bean** : `demo/DemoBean.java`

Pour la tester :
```bash
mvn quarkus:dev
# Puis accédez à http://localhost:8080/components-demo.xhtml
```

Cette page montre tous les composants en action avec un formulaire d'inscription complet.

---

## 🏗️ Architecture

```
primefaces-freya-extension/
├── runtime/
│   └── src/main/resources/
│       └── META-INF/
│           ├── freya.taglib.xml              # Déclaration des 7 composants
│           └── resources/
│               └── freya/                    # Composants composites
│                   ├── fieldInput.xhtml
│                   ├── fieldNumber.xhtml
│                   ├── fieldSelect.xhtml
│                   ├── fieldMultiSelect.xhtml
│                   ├── fieldRadio.xhtml
│                   ├── fieldCalendar.xhtml
│                   ├── fieldPassword.xhtml
│                   ├── fieldTextarea.xhtml
│                   ├── fieldCheckbox.xhtml
│                   ├── fieldSwitch.xhtml
│                   ├── fieldToggle.xhtml
│                   ├── fieldChips.xhtml
│                   ├── fieldRating.xhtml
│                   ├── fieldColor.xhtml
│                   └── actionDialog.xhtml
├── demo/
│   ├── components-demo.xhtml                 # Page de démonstration
│   └── DemoBean.java                         # Backing bean
├── COMPOSANTS_GUIDE.md                       # Documentation complète
├── ANALYSE_OFFICIELLE.md                     # Analyse des sources Freya
└── FREYA_USAGE_GUIDE.md                      # Guide d'usage Freya
```

---

## 🎨 Pattern Freya Appliqué

Tous les composants `fr:field*` génèrent automatiquement cette structure :

```xml
<div class="field">
    <p:outputLabel for="..." value="#{cc.attrs.label}">
        <span class="p-error" rendered="#{cc.attrs.required}"> *</span>
    </p:outputLabel>
    <!-- Composant PrimeFaces natif (p:inputText, p:datePicker, etc.) -->
    <p:message for="..." />
</div>
```

Le composant `fr:fieldCheckbox` utilise `field-checkbox` au lieu de `field` pour un layout horizontal.

---

## ✨ Avantages

### 1. Réduction du Boilerplate

**Sans extension :**
- 10 lignes par champ
- Répétition du pattern `<div class="field">` + label + input + message
- Gestion manuelle de l'astérisque requis

**Avec extension :**
- 1 ligne par champ
- Pattern Freya automatique
- Astérisque requis automatique

### 2. Maintenabilité

Si le pattern Freya change (par exemple structure HTML différente), **un seul fichier à modifier** au lieu de centaines de pages.

### 3. Cohérence

Tous les formulaires utilisent **exactement le même pattern**, garantissant une UX uniforme.

### 4. Compatibilité Totale

Les composants utilisent les composants PrimeFaces standards sous le capot, donc :
- ✅ Toutes les fonctionnalités PrimeFaces disponibles
- ✅ Bean Validation supporté
- ✅ AJAX natif
- ✅ Binding bidirectionnel

---

## 🔧 Personnalisation

### Attributs Communs

Tous les composants `fr:field*` supportent :

| Attribut | Type | Défaut | Description |
|----------|------|--------|-------------|
| `id` | String | - | Identifiant du composant |
| `label` | String | - | Label affiché |
| `value` | Object | - | Valeur liée (two-way binding) |
| `required` | Boolean | `false` | Champ obligatoire (affiche astérisque) |
| `disabled` | Boolean | `false` | Désactive le champ |
| `readonly` | Boolean | `false` | Lecture seule |
| `styleClass` | String | - | Classes CSS additionnelles |

### Attributs Spécifiques

Chaque composant a des attributs spécifiques (voir [COMPOSANTS_GUIDE.md](COMPOSANTS_GUIDE.md)) :

- `fr:fieldInput` : `placeholder`, `maxlength`
- `fr:fieldTextarea` : `rows`, `cols`, `autoResize`
- `fr:fieldPassword` : `feedback`, `toggleMask`
- `fr:fieldSelect` : `filter`, `filterMatchMode`
- `fr:fieldCalendar` : `showIcon`, `pattern`, `yearRange`, `mindate`, `maxdate`
- `fr:actionDialog` : `widgetVar`, `header`, `confirmAction`, `confirmUpdate`

---

## 🔄 Intégration Bean Validation

Les composants supportent pleinement Jakarta Bean Validation :

```java
public class User {
    @NotBlank(message = "Le nom est obligatoire")
    @Size(min = 2, max = 50)
    private String nom;

    @Email(message = "Email invalide")
    private String email;

    @Past(message = "Doit être dans le passé")
    private LocalDate dateNaissance;
}
```

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

Les messages de validation s'affichent automatiquement via `<p:message>`.

---

## 📋 Technologies

- **Quarkus** : 3.15.1
- **Java** : 17+
- **PrimeFaces** : 14.0.0 (Jakarta)
- **Freya Theme** : 5.0.0
- **Jakarta Faces** : 4.0 (Composite Components)
- **PrimeFlex** : 3.3.1 (Grid système)

---

## 🎯 Bonnes Pratiques

### ✅ DO

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

### ❌ DON'T

- Ne pas imbriquer les composants `fr:field*`
- Ne pas dupliquer les labels (le composant le gère)
- Ne pas oublier `widgetVar` sur `fr:actionDialog`
- Ne pas essayer de wrapper tous les composants PrimeFaces (utiliser les composants natifs quand c'est plus simple)

---

## 🚀 Démarrage Rapide

### 1. Cloner le Projet

```bash
git clone <repo-url>
cd primefaces-freya-extension
```

### 2. Installer Localement

```bash
mvn clean install
```

### 3. Utiliser dans un Projet

```xml
<dependency>
    <groupId>dev.lions</groupId>
    <artifactId>primefaces-freya-extension</artifactId>
    <version>1.0.0-SNAPSHOT</version>
</dependency>
```

### 4. Tester la Démo

```bash
cd demo
mvn quarkus:dev
# Ouvrez http://localhost:8080/components-demo.xhtml
```

---

## 📖 Ressources

### Documentation Interne
- [Guide Complet des Composants](COMPOSANTS_GUIDE.md)
- [Analyse Officielle Freya](ANALYSE_OFFICIELLE.md)
- [Guide d'Usage Freya](FREYA_USAGE_GUIDE.md)

### Documentation Externe
- [PrimeFaces 14.0.0](https://primefaces.github.io/primefaces/14_0_0/)
- [Freya Theme](https://freya.primefaces.org/)
- [Jakarta Faces Composite Components](https://jakarta.ee/learn/docs/jakartaee-tutorial/current/web/faces-advanced-cc/)
- [PrimeFlex](https://primeflex.org/)

---

## 📝 License

Le thème Freya est sous **PrimeFaces Commercial License**.
Vérifiez votre licence avant utilisation en production.

---

## 🤝 Contribution

Cette extension a été créée pour l'écosystème Lions mais peut être réutilisée dans tout projet Quarkus + PrimeFaces.

Pour toute question ou suggestion, consultez la documentation complète dans `COMPOSANTS_GUIDE.md`.

---

**Version:** 1.0.0-SNAPSHOT
**Dernière mise à jour:** 2025-12-26
**Composants:** 43 composants composites (Formulaires, Données, Navigation, Actions, Feedback, Utilitaires, Layout, Dialogs)
**Réduction de code:** ~80% sur les formulaires
