Initial commit: PrimeFaces Freya Extension - Composants Freya pour PrimeFaces avec support Quarkus
This commit is contained in:
668
FREYA_USAGE_GUIDE.md
Normal file
668
FREYA_USAGE_GUIDE.md
Normal file
@@ -0,0 +1,668 @@
|
||||
# Guide d'Utilisation - Freya avec PrimeFaces
|
||||
|
||||
**Version** : Freya 5.0.0 + PrimeFaces 14.0.0
|
||||
**Date** : 2025-12-25
|
||||
**Sources** : Documentation officielle Freya et exemples
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Introduction
|
||||
|
||||
Ce guide montre comment utiliser les composants **PrimeFaces standards** avec le thème **Freya** dans vos applications Quarkus, basé sur les exemples officiels de Freya 5.0.0.
|
||||
|
||||
**Important** : Freya est un **thème CSS** pour PrimeFaces, pas une bibliothèque de composants. Vous utilisez les composants PrimeFaces standards (`p:inputText`, `p:dataTable`, etc.) avec les classes CSS de Freya.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Installation
|
||||
|
||||
### 1. Dépendances Maven
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>dev.lions</groupId>
|
||||
<artifactId>primefaces-freya-extension</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
Cette extension fournit :
|
||||
- ✅ Thème Freya
|
||||
- ✅ Templates de layout
|
||||
- ✅ Composant `FreyaMenu`
|
||||
- ✅ Bean `GuestPreferences`
|
||||
|
||||
### 2. Configuration
|
||||
|
||||
**application.properties** :
|
||||
```properties
|
||||
primefaces.THEME=freya
|
||||
primefaces.FONT_AWESOME=true
|
||||
primefaces.CLIENT_SIDE_VALIDATION=true
|
||||
primefaces.MOVE_SCRIPTS_TO_BOTTOM=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Classes CSS Freya
|
||||
|
||||
### Layout Classes (PrimeFlex)
|
||||
|
||||
Freya utilise **PrimeFlex** pour le layout :
|
||||
|
||||
```xml
|
||||
<div class="grid"> <!-- Grille responsive -->
|
||||
<div class="col-12 md:col-6"> <!-- Colonne : 12 cols mobile, 6 desktop -->
|
||||
<div class="card"> <!-- Carte Freya -->
|
||||
<!-- Contenu -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Classes principales** :
|
||||
- `grid` - Conteneur grille
|
||||
- `col-{n}` - Colonnes (1-12)
|
||||
- `md:col-{n}`, `lg:col-{n}` - Breakpoints responsive
|
||||
- `card` - Carte Freya avec ombre et border-radius
|
||||
- `ui-fluid` - Inputs 100% width
|
||||
|
||||
### Form Classes
|
||||
|
||||
**Pattern Field** (recommandé) :
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel for="name" value="Nom" />
|
||||
<p:inputText id="name" value="#{bean.nom}" />
|
||||
<p:message for="name" />
|
||||
</div>
|
||||
```
|
||||
|
||||
**Grid Formgrid** :
|
||||
```xml
|
||||
<div class="grid formgrid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="firstname" value="Prénom" />
|
||||
<p:inputText id="firstname" value="#{bean.prenom}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="lastname" value="Nom" />
|
||||
<p:inputText id="lastname" value="#{bean.nom}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Float Label** :
|
||||
```xml
|
||||
<span class="ui-float-label">
|
||||
<p:inputText id="float-input" value="#{bean.username}" />
|
||||
<p:outputLabel for="@previous" value="Username" />
|
||||
</span>
|
||||
```
|
||||
|
||||
### Icons in Inputs
|
||||
|
||||
```xml
|
||||
<span class="ui-input-icon-left">
|
||||
<i class="pi pi-user"></i>
|
||||
<p:inputText placeholder="Username" />
|
||||
</span>
|
||||
|
||||
<span class="ui-input-icon-right">
|
||||
<p:inputText placeholder="Search" />
|
||||
<i class="pi pi-search"></i>
|
||||
</span>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Composants de Formulaire
|
||||
|
||||
### InputText
|
||||
|
||||
**Basique** :
|
||||
```xml
|
||||
<p:inputText value="#{bean.nom}" placeholder="Nom" />
|
||||
```
|
||||
|
||||
**Avec field pattern** :
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel for="nom" value="Nom" />
|
||||
<p:inputText id="nom" value="#{bean.nom}" required="true" />
|
||||
<p:message for="nom" />
|
||||
</div>
|
||||
```
|
||||
|
||||
**Disabled / Erreur** :
|
||||
```xml
|
||||
<p:inputText value="#{bean.nom}" disabled="true" />
|
||||
<p:inputText value="#{bean.nom}" styleClass="ui-state-error" />
|
||||
```
|
||||
|
||||
### InputTextarea
|
||||
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel for="description" value="Description" />
|
||||
<p:inputTextarea id="description"
|
||||
value="#{bean.description}"
|
||||
rows="5"
|
||||
autoResize="false" />
|
||||
</div>
|
||||
```
|
||||
|
||||
### SelectOneMenu (Dropdown)
|
||||
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel for="category" value="Catégorie" />
|
||||
<p:selectOneMenu id="category" value="#{bean.category}">
|
||||
<f:selectItem itemLabel="Sélectionnez..." itemValue="" />
|
||||
<f:selectItem itemLabel="Option 1" itemValue="1" />
|
||||
<f:selectItem itemLabel="Option 2" itemValue="2" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
```
|
||||
|
||||
**Avec filtre** :
|
||||
```xml
|
||||
<p:selectOneMenu value="#{bean.category}" filter="true" filterMatchMode="contains">
|
||||
<f:selectItems value="#{bean.categories}" />
|
||||
</p:selectOneMenu>
|
||||
```
|
||||
|
||||
### Calendar (DatePicker)
|
||||
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel for="date" value="Date" />
|
||||
<p:datePicker id="date" value="#{bean.date}" showIcon="true" />
|
||||
</div>
|
||||
```
|
||||
|
||||
### SelectManyCheckbox
|
||||
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel value="Options" />
|
||||
<p:selectManyCheckbox value="#{bean.selectedOptions}" layout="responsive" columns="3">
|
||||
<f:selectItem itemLabel="Option 1" itemValue="1" />
|
||||
<f:selectItem itemLabel="Option 2" itemValue="2" />
|
||||
<f:selectItem itemLabel="Option 3" itemValue="3" />
|
||||
</p:selectManyCheckbox>
|
||||
</div>
|
||||
```
|
||||
|
||||
### SelectOneRadio
|
||||
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel value="Catégorie" />
|
||||
<p:selectOneRadio value="#{bean.category}" layout="responsive" columns="2">
|
||||
<f:selectItem itemLabel="Accessories" itemValue="Accessories" />
|
||||
<f:selectItem itemLabel="Clothing" itemValue="Clothing" />
|
||||
</p:selectOneRadio>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Composants de Données
|
||||
|
||||
### DataTable
|
||||
|
||||
**Basique** :
|
||||
```xml
|
||||
<p:dataTable value="#{bean.users}" var="user" paginator="true" rows="10">
|
||||
<p:column headerText="Nom">
|
||||
<h:outputText value="#{user.nom}" />
|
||||
</p:column>
|
||||
<p:column headerText="Email">
|
||||
<h:outputText value="#{user.email}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
```
|
||||
|
||||
**Complet (Pattern Freya CRUD)** :
|
||||
```xml
|
||||
<h:form id="form">
|
||||
<p:growl id="messages" showDetail="true" />
|
||||
|
||||
<!-- Toolbar -->
|
||||
<p:toolbar styleClass="mb-4">
|
||||
<p:toolbarGroup>
|
||||
<p:commandButton value="Nouveau"
|
||||
icon="pi pi-plus"
|
||||
actionListener="#{bean.openNew}"
|
||||
update="dialog-content"
|
||||
oncomplete="PF('dialog').show()"
|
||||
styleClass="ui-button-success" />
|
||||
<p:commandButton value="Supprimer"
|
||||
icon="pi pi-trash"
|
||||
actionListener="#{bean.deleteSelected}"
|
||||
styleClass="ui-button-danger"
|
||||
disabled="#{!bean.hasSelected()}"
|
||||
update="@this">
|
||||
<p:confirm header="Confirmation"
|
||||
message="Supprimer les éléments sélectionnés ?"
|
||||
icon="pi pi-exclamation-triangle" />
|
||||
</p:commandButton>
|
||||
</p:toolbarGroup>
|
||||
<p:toolbarGroup align="right">
|
||||
<p:fileUpload mode="simple" skinSimple="true" label="Import" />
|
||||
<p:commandButton value="Export" icon="pi pi-upload" ajax="false">
|
||||
<p:dataExporter type="pdf" target="dt" fileName="data"/>
|
||||
</p:commandButton>
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
<!-- DataTable -->
|
||||
<p:dataTable id="dt"
|
||||
widgetVar="dtTable"
|
||||
var="item"
|
||||
value="#{bean.items}"
|
||||
selection="#{bean.selectedItems}"
|
||||
rowKey="#{item.id}"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
reflow="true">
|
||||
|
||||
<f:facet name="header">
|
||||
<div class="products-table-header">
|
||||
<span style="font-weight: bold">Gestion des Données</span>
|
||||
<span class="filter-container ui-input-icon-left">
|
||||
<i class="pi pi-search"></i>
|
||||
<p:inputText id="globalFilter"
|
||||
onkeyup="PF('dtTable').filter()"
|
||||
placeholder="Rechercher" />
|
||||
</span>
|
||||
</div>
|
||||
</f:facet>
|
||||
|
||||
<p:ajax event="rowSelect" update=":form:toolbar" />
|
||||
<p:ajax event="rowUnselect" update=":form:toolbar" />
|
||||
|
||||
<p:column selectionMode="multiple" exportable="false" />
|
||||
|
||||
<p:column headerText="Nom" sortBy="#{item.nom}" filterBy="#{item.nom}">
|
||||
<h:outputText value="#{item.nom}" />
|
||||
</p:column>
|
||||
|
||||
<p:column exportable="false">
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
update=":form:dialog-content"
|
||||
oncomplete="PF('dialog').show()"
|
||||
styleClass="edit-button rounded-button ui-button-success">
|
||||
<f:setPropertyActionListener value="#{item}" target="#{bean.selectedItem}" />
|
||||
</p:commandButton>
|
||||
<p:commandButton icon="pi pi-trash"
|
||||
styleClass="ui-button-warning rounded-button"
|
||||
oncomplete="PF('deleteDialog').show()">
|
||||
<f:setPropertyActionListener value="#{item}" target="#{bean.selectedItem}" />
|
||||
</p:commandButton>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</h:form>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Composants Panel
|
||||
|
||||
### Dialog
|
||||
|
||||
**Basique** :
|
||||
```xml
|
||||
<p:dialog header="Détails"
|
||||
widgetVar="dialog"
|
||||
modal="true"
|
||||
showEffect="fade"
|
||||
responsive="true">
|
||||
<p:outputPanel id="dialog-content">
|
||||
<!-- Contenu -->
|
||||
</p:outputPanel>
|
||||
</p:dialog>
|
||||
```
|
||||
|
||||
**Avec formulaire et footer** :
|
||||
```xml
|
||||
<p:dialog header="Éditer"
|
||||
widgetVar="editDialog"
|
||||
modal="true"
|
||||
responsive="true">
|
||||
<p:outputPanel id="edit-content" class="ui-fluid">
|
||||
<p:outputPanel rendered="#{not empty bean.selectedItem}">
|
||||
<div class="field">
|
||||
<p:outputLabel for="name" value="Nom" />
|
||||
<p:inputText id="name" value="#{bean.selectedItem.nom}" required="true" />
|
||||
</div>
|
||||
<div class="field">
|
||||
<p:outputLabel for="description" value="Description" />
|
||||
<p:inputTextarea id="description" value="#{bean.selectedItem.description}" />
|
||||
</div>
|
||||
</p:outputPanel>
|
||||
</p:outputPanel>
|
||||
|
||||
<f:facet name="footer">
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
onclick="PF('editDialog').hide()"
|
||||
styleClass="ui-button-secondary" />
|
||||
<p:commandButton value="Sauvegarder"
|
||||
icon="pi pi-check"
|
||||
actionListener="#{bean.save}"
|
||||
update="edit-content"
|
||||
oncomplete="if(!args.validationFailed) PF('editDialog').hide()"
|
||||
styleClass="ui-button-success" />
|
||||
</f:facet>
|
||||
</p:dialog>
|
||||
```
|
||||
|
||||
### Panel
|
||||
|
||||
```xml
|
||||
<p:panel header="Titre du Panel" toggleable="true" collapsed="false">
|
||||
<p>Contenu du panel...</p>
|
||||
</p:panel>
|
||||
```
|
||||
|
||||
### AccordionPanel
|
||||
|
||||
```xml
|
||||
<p:accordionPanel multiple="false">
|
||||
<p:tab title="Section 1">
|
||||
<p>Contenu de la section 1...</p>
|
||||
</p:tab>
|
||||
<p:tab title="Section 2">
|
||||
<p>Contenu de la section 2...</p>
|
||||
</p:tab>
|
||||
</p:accordionPanel>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔘 Composants Button
|
||||
|
||||
### CommandButton
|
||||
|
||||
**Basique** :
|
||||
```xml
|
||||
<p:commandButton value="Sauvegarder"
|
||||
action="#{bean.save}"
|
||||
update="form" />
|
||||
```
|
||||
|
||||
**Avec icône** :
|
||||
```xml
|
||||
<p:commandButton value="Nouveau"
|
||||
icon="pi pi-plus"
|
||||
actionListener="#{bean.create}" />
|
||||
```
|
||||
|
||||
**Avec styles Freya** :
|
||||
```xml
|
||||
<!-- Success -->
|
||||
<p:commandButton value="Créer"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-success" />
|
||||
|
||||
<!-- Warning -->
|
||||
<p:commandButton value="Attention"
|
||||
icon="pi pi-exclamation-triangle"
|
||||
styleClass="ui-button-warning" />
|
||||
|
||||
<!-- Danger -->
|
||||
<p:commandButton value="Supprimer"
|
||||
icon="pi pi-trash"
|
||||
styleClass="ui-button-danger" />
|
||||
|
||||
<!-- Secondary -->
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
styleClass="ui-button-secondary" />
|
||||
|
||||
<!-- Rounded -->
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="rounded-button ui-button-success" />
|
||||
```
|
||||
|
||||
**Groupe de boutons** :
|
||||
```xml
|
||||
<f:facet name="footer">
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
styleClass="ui-button-secondary" />
|
||||
<p:commandButton value="Sauvegarder"
|
||||
icon="pi pi-check"
|
||||
styleClass="ui-button-success" />
|
||||
</f:facet>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💬 Composants Message
|
||||
|
||||
### Message (pour un champ)
|
||||
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel for="email" value="Email" />
|
||||
<p:inputText id="email" value="#{bean.email}" required="true" />
|
||||
<p:message for="email" />
|
||||
</div>
|
||||
```
|
||||
|
||||
### Messages (tous les messages)
|
||||
|
||||
```xml
|
||||
<h:form>
|
||||
<p:messages id="messages" showDetail="true" closable="true" />
|
||||
<!-- Formulaire -->
|
||||
</h:form>
|
||||
```
|
||||
|
||||
### Growl (notifications toast)
|
||||
|
||||
```xml
|
||||
<h:form>
|
||||
<p:growl id="growl" showDetail="true" />
|
||||
<p:commandButton value="Save"
|
||||
action="#{bean.save}"
|
||||
update="growl" />
|
||||
</h:form>
|
||||
```
|
||||
|
||||
**Dans le bean** :
|
||||
```java
|
||||
public void save() {
|
||||
// Logic...
|
||||
FacesContext.getCurrentInstance().addMessage(null,
|
||||
new FacesMessage(FacesMessage.SEVERITY_INFO,
|
||||
"Succès",
|
||||
"Données sauvegardées avec succès"));
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📐 Patterns de Layout
|
||||
|
||||
### Page Complète avec Card
|
||||
|
||||
```xml
|
||||
<ui:composition template="/WEB-INF/template.xhtml">
|
||||
<ui:define name="title">Ma Page</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h5>Titre</h5>
|
||||
<p>Contenu...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
```
|
||||
|
||||
### Deux Colonnes
|
||||
|
||||
```xml
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="card">
|
||||
<h5>Colonne Gauche</h5>
|
||||
<!-- Contenu -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="card">
|
||||
<h5>Colonne Droite</h5>
|
||||
<!-- Contenu -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Formulaire Complet
|
||||
|
||||
```xml
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<h:form id="userForm" class="ui-fluid">
|
||||
<h5>Nouvel Utilisateur</h5>
|
||||
|
||||
<div class="grid formgrid">
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="firstname" value="Prénom" />
|
||||
<p:inputText id="firstname" value="#{bean.user.firstname}" required="true" />
|
||||
<p:message for="firstname" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6">
|
||||
<div class="field">
|
||||
<p:outputLabel for="lastname" value="Nom" />
|
||||
<p:inputText id="lastname" value="#{bean.user.lastname}" required="true" />
|
||||
<p:message for="lastname" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="email" value="Email" />
|
||||
<p:inputText id="email" value="#{bean.user.email}" required="true" />
|
||||
<p:message for="email" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="role" value="Rôle" />
|
||||
<p:selectOneMenu id="role" value="#{bean.user.role}">
|
||||
<f:selectItem itemLabel="Sélectionnez..." itemValue="" />
|
||||
<f:selectItems value="#{bean.roles}" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:commandButton value="Annuler"
|
||||
icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
style="margin-right: .5rem" />
|
||||
<p:commandButton value="Sauvegarder"
|
||||
icon="pi pi-check"
|
||||
action="#{bean.save}"
|
||||
update="userForm"
|
||||
styleClass="ui-button-success" />
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Composant FreyaMenu
|
||||
|
||||
**Usage** :
|
||||
```xml
|
||||
<html xmlns:fr="http://primefaces.org/freya">
|
||||
|
||||
<fr:menu model="#{menuBean.model}" />
|
||||
```
|
||||
|
||||
**Bean** :
|
||||
```java
|
||||
@Named
|
||||
@SessionScoped
|
||||
public class MenuBean implements Serializable {
|
||||
private MenuModel model;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
model = new DefaultMenuModel();
|
||||
|
||||
DefaultMenuItem item1 = DefaultMenuItem.builder()
|
||||
.value("Dashboard")
|
||||
.icon("pi pi-home")
|
||||
.outcome("/dashboard.xhtml")
|
||||
.build();
|
||||
model.getElements().add(item1);
|
||||
|
||||
DefaultSubMenu subMenu = DefaultSubMenu.builder()
|
||||
.label("Gestion")
|
||||
.icon("pi pi-cog")
|
||||
.build();
|
||||
|
||||
DefaultMenuItem subItem = DefaultMenuItem.builder()
|
||||
.value("Utilisateurs")
|
||||
.outcome("/users/list.xhtml")
|
||||
.build();
|
||||
subMenu.getElements().add(subItem);
|
||||
|
||||
model.getElements().add(subMenu);
|
||||
}
|
||||
|
||||
public MenuModel getModel() {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Ressources
|
||||
|
||||
### Documentation Officielle
|
||||
- **PrimeFaces** : https://primefaces.github.io/primefaces/14_0_0/
|
||||
- **PrimeFlex** : https://www.primefaces.org/primeflex/
|
||||
- **PrimeIcons** : https://www.primefaces.org/primeicons/
|
||||
|
||||
### Exemples Sources Freya
|
||||
- **Localisation** : `C:/Users/dadyo/PersonalProjects/lions-workspace/freya/tag/src/main/webapp/`
|
||||
- Fichiers : `input.xhtml`, `crud.xhtml`, `formlayout.xhtml`, `button.xhtml`, etc.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Bonnes Pratiques
|
||||
|
||||
1. **Utiliser les classes Freya** : `grid`, `card`, `field`, `formgrid`
|
||||
2. **Pattern field cohérent** : Label + Input + Message
|
||||
3. **ui-fluid pour formulaires** : Inputs 100% width
|
||||
4. **Responsive design** : Utiliser `col-12 lg:col-6` etc.
|
||||
5. **Icônes PrimeIcons** : `pi pi-*`
|
||||
6. **Styles de boutons** : `ui-button-success`, `ui-button-danger`, etc.
|
||||
7. **Messages appropriés** : `p:message` pour champs, `p:growl` pour notifications
|
||||
8. **Dialog modal** : Toujours avec `modal="true"` et `responsive="true"`
|
||||
|
||||
---
|
||||
|
||||
**Version** : 1.0.0
|
||||
**Dernière mise à jour** : 2025-12-25
|
||||
Reference in New Issue
Block a user