Version de développement
Cette documentation décrit la version « next » (develop), non encore publiée. Pour la version stable, basculez sur « v5 » dans l'en-tête.
Composants UI

Composants UI Espresso

Référence des composants JavaScript Espresso du desk (bouton, badge, menu déroulant, menu contextuel, notification, panneau inférieur) et de leurs options.

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 :

FormeExempleRésultat
Élémentfrappe.ui.button({...})Élément jQuery, avec ses gestionnaires d'événements (onclick, info-bulle).
Balisagefrappe.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.

OptionValeursRôle
labeltexteTexte du bouton.
variantsolid, subtle (défaut), outline, ghostStyle du bouton.
themegray (défaut), redred pour une action destructive.
sizexs, sm (défaut), md, lgTaille.
icon / icon_left, icon_rightnom LucideIcône avant ou après le libellé. Une icône sans libellé donne un bouton carré : ajoutez alors tooltip ou title.
tooltiptexte ou options d'info-bulleInfo-bulle Espresso au survol et au focus.
hrefURLAffiche un lien <a> à la place d'un <button>.
disabled, loadingbooléenDésactive le bouton ou affiche l'indicateur de chargement.
loading_labeltexteTexte pendant le chargement. « Save », « Delete » et « Submit » ont un texte par défaut.
typebutton (défaut), submit, resetType HTML.
css_class, attrstexte, objetClasses et attributs HTML supplémentaires.
onclickfonctionAction 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);
OptionValeursRôle
labeltexteTexte du badge.
themegray (défaut), blue, green, amber, red, violet, orangeCouleur. orange donne la même couleur que amber.
variantsolid, subtle (défaut), outline, ghostStyle.
sizesm, md (défaut), lgTaille.
icon / icon_left, icon_rightnom LucideIcône avant ou après le libellé.
titletexteInfo-bulle native. Sert aussi d'aria-label sans libellé visible.
css_class, label_class, attrsClasses de l'élément, classes du libellé, attributs HTML.

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() }],
    })
);
OptionRôle
triggerÉlément qui ouvre le menu. Sans trigger, le composant crée un bouton à partir de button.
buttonOptions du bouton déclencheur (voir frappe.ui.button).
optionsTableau 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, offsetPosition par rapport au déclencheur : bottom (défaut), top, left, right, puis start (défaut), center, end, puis l'écart en pixels (4).
empty_textTexte affiché quand aucun élément n'est visible.
on_open, on_closeFonctions appelées à l'ouverture et à la fermeture. on_close reçoit la raison : activate, escape, outside, tab, navigate ou owner.
sheet_on_mobile, sheet_titleSur 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
labelTexte de la ligne.
icon, icon_right, imageIcône avant, icône après, ou image (logo d'application).
descriptionDeuxième ligne, plus petite.
themered pour une action destructive.
selected, disabledChoix courant (visuel), ligne inactive.
shortcutRaccourci affiché, par exemple "ctrl+p". L'affichage seul : liez la touche avec frappe.ui.keys.add_shortcut.
onclickAction au clic. Le menu se ferme ensuite.
href, targetTransforme la ligne en lien.
conditionFonction vérifiée à chaque ouverture. Renvoyez false pour masquer la ligne.
submenuSous-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.

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() },
    ],
});
OptionRô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_textTexte quand aucun élément n'est visible.
on_openAppelée avec l'événement contextmenu, avant l'affichage.
on_closeAppelé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"),
});
OptionValeursRôle
messagetexteTexte principal.
descriptiontexteDeuxième ligne.
typemessage (défaut), info, success, warning, errorIcône et couleur. message n'a pas d'icône.
durationmillisecondes, 5000 par défaut0 garde la notification jusqu'à sa fermeture.
icon, icon_classnom Lucide, classesRemplace l'icône du type.
closablebooléen, true par défautAffiche le bouton de fermeture.
action{ label, onclick }Bouton à droite.
idtexteUne 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 :

OptionRôle
title, subtitleTitre en texte simple, et ligne grisée sous le titre.
headerContenu 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.
contentCorps 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.
optionsLignes 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.
footerContenu fixé en bas, par exemple des boutons frappe.ui.button. Le panneau ne se ferme pas tout seul : appelez sheet.close().
on_showFonction appelée chaque fois que l'étape s'affiche.

Options du panneau :

OptionValeursRôle
triggerélémentÉlément existant qui ouvre le panneau.
buttonoptions de frappe.ui.buttonBouton 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.
heightauto (défaut), half, fullauto s'adapte au contenu, jusqu'à 90 % de l'écran.
snap_pointstableau de half, fullHauteurs entre lesquelles l'utilisateur fait glisser la poignée. Le panneau s'ouvre à la première.
show_closebooléen, false par défautBouton de fermeture dans l'en-tête.
dismissiblebooléen, true par défautUn clic sur le fond, un glissement vers le bas et la touche Échap ferment le panneau.
on_open, on_closefonctionson_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;
}