Molecule List
Molecule List
Le sous-chemin @framework/ui/experimental/List fournit trois composants Vue pour une page de liste :
| Composant | Rôle |
|---|---|
List | Tableau : en-têtes, lignes, tri, sélection, redimensionnement des colonnes. |
ListFooter | Pied de liste : compteur « N sur M », taille de page, bouton « Charger plus ». |
ListBulkBar | Barre flottante d'actions groupées, visible quand des lignes sont sélectionnées. |
Les trois composants affichent des données. Ils ne chargent rien. Votre page charge les lignes, garde l'état et passe les mêmes colonnes (Column[]) et le même tri (Sort[]) que les contrôles ColumnSettings et SortBy.
ListView reste disponible.import { List, ListFooter, ListBulkBar } from "@framework/ui/experimental/List";
List
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
columns | ListColumn[] | [] | Colonnes : { fieldname, label, width?, align? }. align vaut left ou right. |
rows | object[] | [] | Lignes à afficher. |
rowKey | string | "name" | Propriété qui identifie une ligne, pour la sélection. |
loading | boolean | false | Affiche des lignes squelettes. |
rowHeight | number | 40 | Hauteur fixe d'une ligne, en pixels. Nécessaire pour l'affichage virtuel des lignes. |
rowLink | (row) => RouteLocationRaw | — | Route ouverte par une ligne. Chaque ligne devient alors un lien : le clic du milieu et « Copier le lien » fonctionnent. |
gutter | string | — | Marge latérale, en longueur CSS. |
| Modèle | Type | Rôle |
|---|---|---|
v-model:selection | string[] | Clés des lignes cochées. Ajoute la colonne de cases à cocher. |
v-model:sort | Sort[] | Tri : { fieldname, direction: "asc" | "desc" }. Un clic sur un en-tête met la colonne en tri principal. Un deuxième clic inverse l'ordre. |
| Événement | Contenu |
|---|---|
column-resize | { fieldname, width } après un redimensionnement. |
column-reset | { fieldname } après un double-clic sur la poignée. La colonne reprend une largeur automatique. |
Emplacements : #cell (reçoit row, column, value) et #empty (aucune ligne).
ListFooter
| Propriété | Défaut | Rôle |
|---|---|---|
rowCount | 0 | Nombre de lignes chargées. |
totalCount | 0 | Nombre total de lignes. |
hasCounts | false | Mettez true après la première réponse. Avant, le pied affiche un emplacement vide plutôt que « 0 sur 0 ». |
totalCapped | false | Le total est un minimum : il s'affiche suivi de « + ». |
hasNextPage | — | Affiche le bouton « Charger plus ». Sans valeur, les compteurs décident. |
pageSizeOptions | [20, 100, 500, 2500] | Tailles de page proposées. |
Modèle v-model:pageSize (défaut 20). Événements : load-more, et page-size émis seulement quand l'utilisateur clique sur une taille. Écoutez page-size pour distinguer un choix de l'utilisateur d'une valeur restaurée au chargement.
ListBulkBar
| Nom | Rôle |
|---|---|
v-model:selection | Clés sélectionnées. La barre s'affiche quand la liste n'est pas vide. |
actions | Tableau de { label, theme?, onClick(selection) }. theme vaut gray, blue, green ou red. |
La barre affiche le nombre de lignes sélectionnées, les actions et un bouton pour vider la sélection. Elle est en position absolue : placez-la dans un conteneur position: relative.
Exemple
<template>
<div class="relative flex h-full flex-col">
<List
v-model:selection="selection"
v-model:sort="sort"
:columns="columns"
:rows="rows.data ?? []"
:loading="rows.loading"
:row-link="(row) => ({ name: 'Customer', params: { name: row.name } })"
/>
<ListBulkBar
v-model:selection="selection"
:actions="[{ label: 'Supprimer', theme: 'red', onClick: supprimer }]"
/>
<ListFooter
v-model:page-size="pageSize"
:row-count="rows.data?.length ?? 0"
:total-count="total"
:has-counts="rows.fetched"
@load-more="rows.next()"
/>
</div>
</template>
<script setup>
import { ref } from "vue";
import { createListResource } from "frappe-ui";
import { List, ListFooter, ListBulkBar } from "@framework/ui/experimental/List";
const columns = ref([
{ fieldname: "customer_name", label: "Nom" },
{ fieldname: "customer_group", label: "Groupe de clients", width: "12rem" },
]);
const selection = ref([]);
const sort = ref([{ fieldname: "modified", direction: "desc" }]);
const pageSize = ref(20);
const total = ref(0);
const rows = createListResource({
doctype: "Customer",
fields: ["name", "customer_name", "customer_group"],
orderBy: "modified desc",
pageLength: pageSize.value,
auto: true,
});
function supprimer(keys) {
// Exemple fictif : appelez ici votre méthode de suppression groupée.
}
</script>
Exemple fictif : la route Customer dépend du routeur de votre application.