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

Molecule List

Composer une page de liste Vue avec les composants expérimentaux List, ListFooter et ListBulkBar de @framework/ui.

Molecule List

Le sous-chemin @framework/ui/experimental/List fournit trois composants Vue pour une page de liste :

ComposantRôle
ListTableau : en-têtes, lignes, tri, sélection, redimensionnement des colonnes.
ListFooterPied de liste : compteur « N sur M », taille de page, bouton « Charger plus ».
ListBulkBarBarre 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.

Ce module est expérimental. Son API peut changer sans période de dépréciation. Le module ListView reste disponible.
import { List, ListFooter, ListBulkBar } from "@framework/ui/experimental/List";

List

PropriétéTypeDéfautRôle
columnsListColumn[][]Colonnes : { fieldname, label, width?, align? }. align vaut left ou right.
rowsobject[][]Lignes à afficher.
rowKeystring"name"Propriété qui identifie une ligne, pour la sélection.
loadingbooleanfalseAffiche des lignes squelettes.
rowHeightnumber40Hauteur 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.
gutterstring—Marge latérale, en longueur CSS.
ModèleTypeRôle
v-model:selectionstring[]Clés des lignes cochées. Ajoute la colonne de cases à cocher.
v-model:sortSort[]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énementContenu
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éfautRôle
rowCount0Nombre de lignes chargées.
totalCount0Nombre total de lignes.
hasCountsfalseMettez true après la première réponse. Avant, le pied affiche un emplacement vide plutôt que « 0 sur 0 ».
totalCappedfalseLe 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

NomRôle
v-model:selectionClés sélectionnées. La barre s'affiche quand la liste n'est pas vide.
actionsTableau 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.