Composants UI Espresso
Composants UI Espresso
Espresso est le système de composants du desk. Chaque composant est une fonction de frappe.ui. Le code se trouve dans frappe/public/js/frappe/ui/components/.
La plupart des composants existent sous deux formes :
| Forme | Exemple | Résultat |
|---|---|---|
| Élément | frappe.ui.button({...}) | Élément jQuery, avec ses gestionnaires d'événements (onclick, info-bulle). |
| Balisage | frappe.ui.button.html({...}) | Chaîne HTML, sans gestionnaire. Utile dans une vue de liste construite en chaînes. |
Les icônes sont des noms d'icônes Lucide : "check", "trash-2", "printer". Les libellés sont affichés comme texte, jamais comme HTML : traduisez-les avec __() avant de les passer.
L'Explorateur de composants montre chaque composant avec des exemples.
D'autres composants Espresso ont leur propre page : Stepper, Sections optionnelles, Groupe d'avatars, Skeleton et Divider, Menus déroulants et Info-bulles intelligentes.
Les composants Vue des applications (paquet @framework/ui, construit sur frappe-ui) sont décrits à part : voir Package @framework/ui.
Bouton : frappe.ui.button
const $btn = frappe.ui.button({
label: __("Save"),
variant: "solid",
icon: "check",
onclick: () => frm.save(),
});
$btn.appendTo(frm.fields_dict.actions_html.$wrapper);
Si onclick renvoie une promesse, le bouton affiche un indicateur de chargement jusqu'à la fin de la promesse.
| Option | Valeurs | Rôle |
|---|---|---|
label | texte | Texte du bouton. |
variant | solid, subtle (défaut), outline, ghost | Style du bouton. |
theme | gray (défaut), red | red pour une action destructive. |
size | xs, sm (défaut), md, lg | Taille. |
icon / icon_left, icon_right | nom Lucide | Icône avant ou après le libellé. Une icône sans libellé donne un bouton carré : ajoutez alors tooltip ou title. |
tooltip | texte ou options d'info-bulle | Info-bulle Espresso au survol et au focus. |
href | URL | Affiche un lien <a> à la place d'un <button>. |
disabled, loading | booléen | Désactive le bouton ou affiche l'indicateur de chargement. |
loading_label | texte | Texte pendant le chargement. « Save », « Delete » et « Submit » ont un texte par défaut. |
type | button (défaut), submit, reset | Type HTML. |
css_class, attrs | texte, objet | Classes et attributs HTML supplémentaires. |
onclick | fonction | Action au clic (forme élément seulement). |
frappe.ui.button.dress(el, opts) applique le style Espresso à un bouton qui existe déjà.
Badge : frappe.ui.badge
frappe.ui.badge({ label: __("Overdue"), theme: "red" }).appendTo($row);
| Option | Valeurs | Rôle |
|---|---|---|
label | texte | Texte du badge. |
theme | gray (défaut), blue, green, amber, red, violet, orange | Couleur. orange donne la même couleur que amber. |
variant | solid, subtle (défaut), outline, ghost | Style. |
size | sm, md (défaut), lg | Taille. |
icon / icon_left, icon_right | nom Lucide | Icône avant ou après le libellé. |
title | texte | Info-bulle native. Sert aussi d'aria-label sans libellé visible. |
css_class, label_class, attrs | Classes de l'élément, classes du libellé, attributs HTML. |
Menu déroulant : frappe.ui.Dropdown
Le menu s'ouvre sur un élément déclencheur. Il remplace l'attribut Bootstrap data-toggle="dropdown".
new frappe.ui.Dropdown({
trigger: $(".menu-btn"),
options: [
{ label: __("Edit"), icon: "pen", onclick: () => edit() },
{ label: __("Delete"), icon: "trash", theme: "red", onclick: () => remove() },
],
});
La forme courte frappe.ui.dropdown(opts) crée aussi le bouton déclencheur et le renvoie. L'instance est dans .data("es-dropdown").
page.body.append(
frappe.ui.dropdown({
button: { label: __("Actions") },
options: [{ label: __("Duplicate"), onclick: () => duplicate() }],
})
);
| Option | Rôle |
|---|---|
trigger | Élément qui ouvre le menu. Sans trigger, le composant crée un bouton à partir de button. |
button | Options du bouton déclencheur (voir frappe.ui.button). |
options | Tableau d'éléments ou de groupes. Une fonction est appelée à chaque ouverture et peut renvoyer une promesse : le menu affiche une ligne de chargement en attendant. |
side, align, offset | Position par rapport au déclencheur : bottom (défaut), top, left, right, puis start (défaut), center, end, puis l'écart en pixels (4). |
empty_text | Texte affiché quand aucun élément n'est visible. |
on_open, on_close | Fonctions appelées à l'ouverture et à la fermeture. on_close reçoit la raison : activate, escape, outside, tab, navigate ou owner. |
sheet_on_mobile, sheet_title | Sur téléphone, ouvre les éléments dans un panneau frappe.ui.BottomSheet. |
Méthodes de l'instance : open(), close(), toggle(), set_options(options), destroy().
Éléments de menu
| Clé | Rôle |
|---|---|
label | Texte de la ligne. |
icon, icon_right, image | Icône avant, icône après, ou image (logo d'application). |
description | Deuxième ligne, plus petite. |
theme | red pour une action destructive. |
selected, disabled | Choix courant (visuel), ligne inactive. |
shortcut | Raccourci affiché, par exemple "ctrl+p". L'affichage seul : liez la touche avec frappe.ui.keys.add_shortcut. |
onclick | Action au clic. Le menu se ferme ensuite. |
href, target | Transforme la ligne en lien. |
condition | Fonction vérifiée à chaque ouverture. Renvoyez false pour masquer la ligne. |
submenu | Sous-menu : tableau, ou fonction qui renvoie les éléments ou une promesse. |
Pour un groupe, passez { group: "Titre", hide_label: false, options: [...] }.
Le clavier fonctionne dans tous les menus : flèches pour se déplacer, droite et gauche pour les sous-menus, Entrée ou Espace pour choisir, Échap pour fermer. Une lettre saisie va à la ligne qui commence par cette lettre. Maintenir Alt souligne une lettre par ligne : Alt + cette lettre choisit la ligne.
Menu contextuel : frappe.ui.ContextMenu
Le menu s'ouvre au clic droit sur un élément, à la position du pointeur. Il accepte les mêmes éléments que frappe.ui.Dropdown.
new frappe.ui.ContextMenu({
target: row_el,
options: () => [
{ label: __("Open"), icon: "external-link", onclick: () => open_row() },
{ label: __("Delete"), icon: "trash-2", theme: "red", onclick: () => delete_row() },
],
});
| Option | Rôle |
|---|---|
target | Élément qui reçoit le clic droit. Obligatoire. |
options | Éléments, ou fonction appelée à chaque ouverture (elle peut renvoyer une promesse). |
empty_text | Texte quand aucun élément n'est visible. |
on_open | Appelée avec l'événement contextmenu, avant l'affichage. |
on_close | Appelée avec la raison de fermeture. |
Pendant l'ouverture, la cible porte l'attribut data-state="open". Utilisez-le pour mettre en évidence la ligne concernée.
Notification : frappe.ui.toast
frappe.ui.toast({ message: __("Saved"), type: "success" });
frappe.ui.toast.promise(frm.save(), {
loading: __("Saving..."),
success: __("Saved"),
});
| Option | Valeurs | Rôle |
|---|---|---|
message | texte | Texte principal. |
description | texte | Deuxième ligne. |
type | message (défaut), info, success, warning, error | Icône et couleur. message n'a pas d'icône. |
duration | millisecondes, 5000 par défaut | 0 garde la notification jusqu'à sa fermeture. |
icon, icon_class | nom Lucide, classes | Remplace l'icône du type. |
closable | booléen, true par défaut | Affiche le bouton de fermeture. |
action | { label, onclick } | Bouton à droite. |
id | texte | Une deuxième notification avec le même id met à jour la première. |
frappe.ui.toast() renvoie { id, $el, dismiss, update }.
Panneau inférieur : frappe.ui.BottomSheet
Le panneau inférieur monte depuis le bas de l'écran. Il sert aux choix, aux formulaires courts et aux confirmations sur téléphone. La page derrière est assombrie et le focus reste dans le panneau jusqu'à sa fermeture.
Le composant ne fait pas partie des bundles du desk. Chargez son script et ses styles avant la première utilisation :
await frappe.require(["bottom_sheet.bundle.js", "bottom_sheet.bundle.css"]);
new frappe.ui.BottomSheet({
title: __("Sort by"),
options: [{ label: __("Created On"), selected: true, onclick: () => sort("creation") }],
}).open();
La forme courte frappe.ui.bottom_sheet(opts) crée un bouton déclencheur (option button) et le renvoie, sans ouvrir le panneau. Ajoutez ce bouton dans la page. L'instance est dans .data("es-bottom-sheet").
toolbar.append(
frappe.ui.bottom_sheet({
button: { label: __("Sort"), icon: "arrow-down-wide-narrow" },
title: __("Sort by"),
options: sort_options,
})
);
Options d'une étape :
| Option | Rôle |
|---|---|
title, subtitle | Titre en texte simple, et ligne grisée sous le titre. |
header | Contenu fixé en haut : champ de recherche, onglets. Un élément, un tableau d'éléments, une chaîne ou une fonction qui reçoit le panneau. |
content | Corps qui défile. Un élément ou une fonction appelée à la première ouverture de l'étape. Une chaîne est affichée comme texte. |
options | Lignes cliquables, sous le contenu : { label, icon, description, theme, selected, disabled, onclick(e, sheet) } et groupes { group, options }. Un clic exécute onclick puis ferme le panneau, sauf si onclick renvoie false. |
footer | Contenu fixé en bas, par exemple des boutons frappe.ui.button. Le panneau ne se ferme pas tout seul : appelez sheet.close(). |
on_show | Fonction appelée chaque fois que l'étape s'affiche. |
Options du panneau :
| Option | Valeurs | Rôle |
|---|---|---|
trigger | élément | Élément existant qui ouvre le panneau. |
button | options de frappe.ui.button | Bouton déclencheur créé par le composant (ignoré avec trigger). |
anchor | élément | Élément concerné, par exemple une carte. Sur un écran plus large qu'un téléphone, le panneau s'ouvre en fenêtre contextuelle à côté de lui. |
height | auto (défaut), half, full | auto s'adapte au contenu, jusqu'à 90 % de l'écran. |
snap_points | tableau de half, full | Hauteurs entre lesquelles l'utilisateur fait glisser la poignée. Le panneau s'ouvre à la première. |
show_close | booléen, false par défaut | Bouton de fermeture dans l'en-tête. |
dismissible | booléen, true par défaut | Un clic sur le fond, un glissement vers le bas et la touche Échap ferment le panneau. |
on_open, on_close | fonctions | on_close reçoit la raison : scrim, swipe, escape, close, option, route, owner ou la valeur passée à sheet.close(reason). |
Méthodes : open(), close(reason), toggle(), push(step) (ajoute une étape et affiche le bouton Retour), pop(), set_title(title, subtitle), set_options(options) et set_height(height). Un choix qui en appelle un autre est une étape ajoutée avec push(), pas un deuxième panneau. Un changement de page ferme le panneau.
Info-bulle : frappe.ui.tooltip
frappe.ui.tooltip($btn, { text: __("Refresh"), shortcut: "ctrl+r" });
Les options principales sont text, side, align, delay (500 ms par défaut), shortcut et only_on_overflow. Voir Info-bulles intelligentes.
Personnaliser les styles
Les composants portent des classes es-* (es-button, es-badge, es-avatar-group…) et des attributs data-variant, data-size, data-theme. Les styles se trouvent dans frappe/public/css/espresso/. Pour adapter un composant, ciblez ces classes et attributs dans le CSS de votre application.
.es-button[data-variant="solid"] {
font-weight: 600;
}