Components
All available UI components with usage examples.
Badge
Variants
With icons
Alert
Information
EJS UI-KIT - Components
Warning
Error
Spinner
Indicateur de chargement CSS-only. S'intègre dans les boutons, cards ou sections.
Tailles
Bouton — prop loading (SSR)
Bouton — toggle JS setLoading()
Skeleton
Placeholder CSS-only pour le contenu en cours de chargement. Trois presets et un mode custom.
Text
Card
List
Custom — classe .ui-skeleton directement
Card
Card title
Card subtitle or description
Card body content goes here. It can contain any HTML.
Simple card with inline padding, no header/footer slots needed.
Modal
Drawer
Sliding Drawer
A panel anchored to a screen edge with a persistent grab handle. Click or drag to open/close. Backdrop opacity follows drag progress.
side="right"
Right panel
Drag or click the handle. Backdrop follows the drag.
side="left"
Left panel
Handle is on the right edge of the panel.
side="bottom"
Bottom panel
Horizontal grip at the top edge.
side="top"
Top panel
Slides down from the top edge.
size="full"
side="right" size="full"
Full height
Panel spans 100dvh. Body scrolls if content overflows.
side="bottom" size="full"
Full width
Panel spans 100vw. Useful for mobile action sheets.
handle variants
handle="arrow"
Arrow
Flips when open.
handle="icon"
Icon
Any Lucide icon.
handle="text"
Text
Custom label.
Accordion
mode: "single" — un seul panneau ouvert à la fois
src/views/ui/, a JS module in public/ui/components/, register it in the loader map, and add CSS in assets/css/input.css.mode: "multiple" — plusieurs panneaux peuvent rester ouverts simultanément
open: true — panneau ouvert au chargement
open: true.Dropdown
Tooltip
Popover
Toast
Variants
Positions
Toasts are triggered via JavaScript — no EJS include needed. One container per position is injected automatically on first use.
Tabs
Navigation par onglets accessible (ARIA). Chaque onglet peut recevoir une icône Lucide positionnée au début ou à la fin du label. L'onglet actif au chargement est défini par active: true sur l'item correspondant.
Sans icône
Manage your account settings and preferences.
Change your password here.
Configure how you receive notifications.
Avec icônes
Paramètres du compte.
Mot de passe et authentification.
Préférences de notification.
Onglet actif par défaut (2e)
Vue générale du projet.
Historique des actions récentes.
Gérez les membres de l'équipe.
Navigation clavier
Table
Composant de style : les classes CSS gèrent l'apparence, le JS gère le tri (clic → event table:sort), le choix du nombre de lignes, et les offsets des lignes/colonnes figées.
Le rechargement des données reste à la charge de l'application.
Basique
| Rôle | Statut | ||
|---|---|---|---|
| Alice Martin | alice@example.com | Admin | Actif |
| Bob Dupont | bob@example.com | Éditeur | Actif |
| Clara Schmidt | clara@example.com | Lecteur | En attente |
| David Leroy | david@example.com | Éditeur | Inactif |
| Eva Nguyen | eva@example.com | Lecteur | Actif |
Tri actif (name asc)
| Alice Martin | Pro | 12 jan. 2024 | 29,00 € |
| Bob Dupont | Gratuit | 03 mar. 2024 | 0,00 € |
| Clara Schmidt | Entreprise | 27 nov. 2023 | 99,00 € |
Striped + compact
| Pays | Code | Utilisateurs |
|---|---|---|
| France | FR | 12 483 |
| Allemagne | DE | 9 201 |
| Espagne | ES | 7 654 |
| Italie | IT | 6 890 |
| Pays-Bas | NL | 4 312 |
| Belgique | BE | 3 107 |
Sélection de lignes
| Nom | Équipe | Statut | ||
|---|---|---|---|---|
| Alice Martin | alice@example.com | Produit | Actif | |
| Bob Dupont | bob@example.com | Support | Actif | |
| Clara Schmidt | clara@example.com | Finance | En attente | |
| David Leroy | david@example.com | Ops | Verrouillé |
Lignes + colonnes figées
| Équipe | Owner | Jan | Fév | Mar | Avr | Mai | Juin | Juil | Août | Total |
|---|---|---|---|---|---|---|---|---|---|---|
| Total | Toutes équipes | 1 245 | 1 382 | 1 517 | 1 604 | 1 721 | 1 890 | 1 943 | 2 031 | 13 333 |
| Acquisition | Lina Moreau | 182 | 210 | 238 | 249 | 272 | 301 | 318 | 330 | 2 100 |
| Activation | Hugo Bernard | 154 | 168 | 191 | 207 | 225 | 248 | 263 | 276 | 1 732 |
| Retention | Nora Klein | 203 | 229 | 251 | 268 | 294 | 327 | 341 | 359 | 2 272 |
| Support | Marc Vidal | 121 | 137 | 145 | 153 | 166 | 181 | 194 | 202 | 1 299 |
| Finance | Emma Rossi | 98 | 104 | 116 | 123 | 131 | 144 | 149 | 155 | 1 020 |
| Produit | Sofia Martin | 173 | 192 | 216 | 229 | 244 | 267 | 281 | 296 | 1 898 |
| Data | Noah Dubois | 133 | 148 | 167 | 178 | 191 | 209 | 218 | 231 | 1 475 |
| Ops | Iris Lefèvre | 94 | 106 | 118 | 129 | 141 | 153 | 160 | 169 | 1 070 |
| Partenariats | Tom Alvarez | 87 | 88 | 75 | 68 | 57 | 60 | 19 | 13 | 467 |
État vide
| Nom | Rôle | |
|---|---|---|
| Aucun utilisateur trouvé. | ||
Pagination
Composant générique pour paginer une table, une liste, une galerie ou une grille. Il expose le choix de page via pagination:page-change.
La récupération des données reste à la charge de l'application.
Résultats paginés
Faible volume (10 pages)
Grand volume
Form controls
Input
We'll never share your email.
This field is required.
Textarea & Select
Checkbox & Radio
Checkboxes
Receive product updates and news.
Input
Textarea
Select
Checkbox
Radio
Select Search
Select avec champ de filtrage des options. Clavier : flèches pour naviguer, Entrée pour sélectionner, Échap pour fermer.
Tapez pour filtrer la liste.
Ce champ est requis.
Autocomplete
Champ texte avec suggestions récupérées depuis le backend. Supporte la navigation clavier, l'annulation des requêtes en vol et l'auto-sélection sur correspondance exacte unique.
Les suggestions arrivent après 1 caractère.
Affichage résolu via fetchByIdUrl au chargement.
Upload
Zone de dépôt de fichier. Supporte trois modes d'interaction : clic (sélecteur natif), glisser-déposer et collage (Ctrl+V) depuis le presse-papier. La validation du type et de la taille s'applique dans les trois cas côté client. Supporte un ou plusieurs fichiers, les miniatures images et le mode édition (fichiers préchargés depuis le serveur).
Votre CV sera transmis aux recruteurs. Formats acceptés : PDF.
Ce champ est requis.
Mode édition — fichier existant
Le fichier préchargé est affiché dès le rendu côté serveur. Supprimer le fichier efface la valeur du champ caché. Sélectionner un nouveau fichier remplace automatiquement l'existant.
- contrat-2024.pdf 181.9 Ko
Mode édition — plusieurs fichiers existants
Chaque fichier existant produit un <input type="hidden" name="photos_existing[]">. La valeur est vidée si l'utilisateur supprime l'entrée. Les nouveaux fichiers s'ajoutent à la liste.
-
photo-1.jpg
82.2 Ko
-
photo-2.jpg
100.0 Ko
| Prop | Type | Défaut | Description |
|---|---|---|---|
| id | string | auto | Identifiant HTML unique. Lié au <input type="file"> et aux champs cachés. |
| name | string | id | Attribut name du champ. Détermine aussi le nom des champs cachés pour les fichiers existants (name_existing / name_existing[]). |
| label | string | — | Libellé affiché au-dessus de la zone. Omis si non renseigné. |
| accept | string | — | Types acceptés. Appliqué au sélecteur natif et validé côté JS pour le drag & drop et le collage. Syntaxe : MIME (image/*, application/pdf) ou extensions (.pdf,.docx), combinables. |
| multiple | boolean | false | Autorise la sélection de plusieurs fichiers. En mode single, chaque nouvelle sélection remplace la précédente et efface les fichiers existants. |
| maxSize | number | — | Taille maximale par fichier en octets. Validation JS — les fichiers trop lourds sont refusés avec un message d'erreur. S'applique au sélecteur, au drag & drop et au collage. |
| placeholder | string | auto | Texte cliquable de la zone d'upload (partie soulignée). Par défaut : "Choisir un fichier" ou "Choisir des fichiers" selon multiple. |
| subtext | string | auto | Texte secondaire à droite du placeholder. Par défaut : "ou glisser-déposer", avec "ou survoler et coller l'image" ajouté automatiquement si accept inclut des images. Passer "" pour supprimer. |
| hint | string | — | Texte de format affiché sous le placeholder (ex. "PNG, JPG — 5 Mo max"). |
| preview | boolean | false | Affiche une miniature pour chaque fichier image sélectionné (nouveaux fichiers et fichiers existants si type est renseigné). |
| existingFiles | Array | [] | Fichiers préchargés pour le mode édition. Chaque entrée : { name, url, size?, type? }. Produit un <input type="hidden"> dont la valeur est effacée à la suppression. |
| helpText | string | — | Texte d'aide affiché sous la zone. Masqué si errorText est renseigné. |
| errorText | string | — | Message d'erreur SSR affiché sous la zone. Ajoute un contour rouge sur la zone. Prioritaire sur helpText. |
| required | boolean | false | Ajoute un marqueur * sur le label et l'attribut required sur le champ natif. |
| disabled | boolean | false | Désactive toutes les interactions (clic, drag & drop, collage). Applique un style visuel atténué. |
value du hidden est vidée (""). En mode single, sélectionner un nouveau fichier vide aussi le hidden.Timeline
Composant de frise chronologique. Supporte trois layouts (vertical, alterné, horizontal), des variantes de statut sur les nœuds, et deux modes d'usage : données (items) ou markup libre (timeline-item imbriqués).
Vertical — statuts & icônes
Commande passée
En préparation
Expédié
Livraison
Vertical — dots simples
Fondation
Série A
Expansion
Scale
International
Alterné
Fondation
Série A
Expansion
Scale
International
Horizontal — étapes de processus
Panier
Livraison
Paiement
Confirmation
Markup libre — corps HTML personnalisé
Contrat signé
Accès créé
alice@example.com.Onboarding
Étapes numérotées — auto ascendant
Création du compte
Vérification e-mail
Configuration du profil
Invitation des membres
Première publication
Étapes numérotées — auto descendant
Lancement v3
Tests de charge
Code freeze
Recette QA
Horizontal — nodeStep libre
Panier
Livraison
Paiement
Confirmation
| Prop | Composant | Type | Défaut | Description |
|---|---|---|---|---|
| layout | timeline | string | 'vertical' | vertical | alternating | horizontal |
| step | timeline | string | — | Numérotation auto en mode données — 'asc' (1, 2, 3…) ou 'desc' (N…1). Ignoré si l'item définit nodeStep. |
| items | timeline | Array | — | Mode données — tableau d'objets item. Si absent, utilise body. |
| body | timeline | string | — | Mode markup libre — HTML pré-rendu (includes timeline-item). |
| date | timeline-item | string | — | Label temporel affiché au-dessus du titre. |
| title | timeline-item | string | — | Titre de l'événement. |
| body | timeline-item | string | — | Contenu HTML du corps. Rendu via <%-. |
| nodeIcon | timeline-item | string | — | Nom d'icône Lucide affiché dans le nœud. Prioritaire sur nodeStep. |
| nodeStep | timeline-item | string | number | — | Chiffre ou texte court affiché dans le nœud. Remplace le dot. Peut être passé manuellement ou injecté via step sur le parent. |
| status | timeline-item | string | 'default' | default | success | warning | error | info | muted. Colore le nœud. |
| active | timeline-item | boolean | false | Marque l'étape courante — nœud en couleur primaire avec anneau de focus. Prioritaire sur status. |
Progress Bar
Barre de progression configurable. Supporte les couleurs du design system, plusieurs tailles, les positions de texte externes ou internes, les rayures et un mode indéterminé.
Couleurs
Tailles
Position du texte — extérieur
Position du texte — intérieur (labels courts)
Rayures
Mode indéterminé
Editor
Éditeur de texte riche basé sur Quill v2. Charge Quill en lazy (CSS + JS) au premier rendu. La valeur est synchronisée dans un <input type="hidden"> pour la soumission de formulaire.
Toolbar complète (défaut)
Toolbar minimale
Mise en forme de base uniquement.
Valeur initiale + état d'erreur
Ce champ est requis.