Tables & DataGrid
Le composant BcDataGrid fournit un tableau de donnees complet avec tri, selection multiple et actions par ligne.
Demo live avancee — BcDataGrid avec toolbar et badges risque
Filtres avances + saved views
DataGrid avec selection multi, tri et actions bulk
| SIREN | |||||
|---|---|---|---|---|---|
| Corp Alpha | 823 456 789 | Actif | Faible | - | |
| FinServ Beta | 445 678 912 | Bloqué | Élevé | - | |
| NeoBank Gamma | 917 234 567 | Setup | Moyen | - |
vue
<script setup>
import { ref } from 'vue'
const items = ref([
{ nom: 'Corp Alpha', siren: '823 456 789', statut: 'Actif', risque: 'Faible' },
{ nom: 'NeoBank Gamma', siren: '917 234 567', statut: 'Setup', risque: 'Moyen' },
{ nom: 'FinServ Beta', siren: '445 678 912', statut: 'Bloqué', risque: 'Élevé' },
])
const fields = [
{ key: 'nom', label: 'Entreprise', sortable: true },
{ key: 'siren', label: 'SIREN', sortable: false },
{ key: 'statut', label: 'Statut', sortable: true },
{ key: 'risque', label: 'Risque', sortable: true },
{ key: 'actions', label: '' },
]
const selected = ref([])
const riskVariant = (val) => ({ Faible: 'success', Moyen: 'warning', Élevé: 'danger' }[val] || 'secondary')
</script>
<!-- Barre d'actions bulk (en dehors du DataGrid) -->
<div style="display: flex; gap: 8px; margin-bottom: 12px;">
<bc-button variant="ghost" size="sm" :disabled="!selected.length">
Exporter ({{ selected.length }})
</bc-button>
<bc-button variant="ghost" size="sm" :disabled="!selected.length">Bulk approve</bc-button>
<bc-button variant="ghost" size="sm" :disabled="!selected.length">Bulk reject</bc-button>
</div>
<BcDataGrid
v-model="selected"
:rows="items"
:columns="fields"
selectable
initial-sort-key="nom"
initial-sort-direction="asc"
>
<template #cell-risque="{ value }">
<bc-badge :variant="riskVariant(value)">{{ value }}</bc-badge>
</template>
</BcDataGrid>Snippet saved views
html
<div class="bc-saved-views" style="display: flex; gap: 8px; margin-bottom: 16px;">
<button aria-pressed="true" class="bc-view-btn active">Tous</button>
<button aria-pressed="false" class="bc-view-btn">KYB validé</button>
<button aria-pressed="false" class="bc-view-btn">Score > 70</button>
<button aria-pressed="false" class="bc-view-btn">+ Nouvelle vue</button>
</div>Basique
| Statut | |||
|---|---|---|---|
| Alice Martin | alice@example.com | Admin | Actif |
| Bob Dupont | bob@example.com | Editeur | Actif |
| Claire Moreau | claire@example.com | Lecteur | Inactif |
| David Bernard | david@example.com | Admin | Actif |
| Emma Petit | emma@example.com | Editeur | Actif |
| Fabien Roux | fabien@example.com | Lecteur | Suspendu |
| Gabrielle Leroy | gabrielle@example.com | Editeur | Actif |
| Hugo Lambert | hugo@example.com | Lecteur | Actif |
vue
<script setup>
const columns = [
{ key: 'name', label: 'Nom', sortable: true },
{ key: 'email', label: 'Email', sortable: true },
{ key: 'role', label: 'Role', sortable: true },
{ key: 'status', label: 'Statut' },
]
const rows = [
{ id: 1, name: 'Alice Martin', email: 'alice@example.com', role: 'Admin', status: 'Actif' },
// ...
]
</script>
<BcDataGrid :columns="columns" :rows="rows" />Avec selection
| Statut | Actions | ||||
|---|---|---|---|---|---|
| Alice Martin | alice@example.com | Admin | Actif | ||
| Bob Dupont | bob@example.com | Editeur | Actif | ||
| Claire Moreau | claire@example.com | Lecteur | Inactif | ||
| David Bernard | david@example.com | Admin | Actif | ||
| Emma Petit | emma@example.com | Editeur | Actif | ||
| Fabien Roux | fabien@example.com | Lecteur | Suspendu | ||
| Gabrielle Leroy | gabrielle@example.com | Editeur | Actif | ||
| Hugo Lambert | hugo@example.com | Lecteur | Actif |
vue
<BcDataGrid v-model="selected" :columns="columns" :rows="rows"
selectable :actions="actions" />Tri initial
| Statut | |||
|---|---|---|---|
| Alice Martin | alice@example.com | Admin | Actif |
| Bob Dupont | bob@example.com | Editeur | Actif |
| Claire Moreau | claire@example.com | Lecteur | Inactif |
| David Bernard | david@example.com | Admin | Actif |
| Emma Petit | emma@example.com | Editeur | Actif |
| Fabien Roux | fabien@example.com | Lecteur | Suspendu |
| Gabrielle Leroy | gabrielle@example.com | Editeur | Actif |
| Hugo Lambert | hugo@example.com | Lecteur | Actif |
vue
<BcDataGrid :columns="columns" :rows="rows"
initial-sort-key="name" initial-sort-direction="asc" />Etat vide
| Statut | |||
|---|---|---|---|
| Aucun résultat | |||
Pagination et tri serveur
Pour les listes volumineuses, deleguez tri/pagination au backend.
vue
<script setup>
import { ref, watch } from 'vue'
const sort = ref({ key: 'nom', direction: 'asc' })
const page = ref(1)
const pageSize = ref(25)
const total = ref(0)
const rows = ref([])
const loading = ref(false)
async function fetchData() {
loading.value = true
const res = await api.getFinancialServices({
sort: sort.value,
page: page.value,
pageSize: pageSize.value,
})
rows.value = res.items
total.value = res.total
loading.value = false
}
watch([sort, page], fetchData, { immediate: true })
</script>
<BcDataGrid
:columns="fields"
:rows="rows"
:loading="loading"
server-sort
@sort-change="sort = $event"
/>
<BcPagination v-model="page" :total="total" :page-size="pageSize" />Chargement et erreur
vue
<template v-if="loading && !rows.length">
<BcSkeleton :lines="1" :widths="['60%']" />
<BcSkeleton v-for="n in 5" :key="n" :lines="1" :widths="['90%']" />
</template>
<template v-else-if="error">
<BcAlert variant="danger" :title="error.title" :message="error.message">
<BcButton variant="outline" size="sm" @click="fetchData">Reessayer</BcButton>
</BcAlert>
</template>
<template v-else>
<BcDataGrid :columns="fields" :rows="rows" />
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
rows | GridRow[] | [] | Donnees du tableau |
columns | GridColumn[] | [] | Definition des colonnes { key, label, sortable?, width? } |
rowKey | string | "id" | Cle unique des lignes |
rowLabelKey | string | "name" | Cle pour le label accessible |
actions | GridAction[] | [] | Actions par ligne { id, label } |
selectable | boolean | false | Active la selection multiple |
modelValue | unknown[] | [] | Lignes selectionnees (v-model) |
initialSortKey | string | null | null | Colonne de tri initial |
initialSortDirection | "asc" | "desc" | null | null | Direction du tri initial |
emptyText | string | "Aucune donnee" | Texte etat vide |
ariaLabel | string | "Tableau de donnees" | Label ARIA |
Slots
| Slot | Description |
|---|---|
header-{key} | En-tete personnalise pour une colonne |
cell-{key} | Cellule personnalisee pour une colonne |
actions | Actions personnalisees par ligne |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | unknown[] | Changement de selection |
row-action | { actionId, row } | Action declenchee sur une ligne |
sort-change | { key, direction } | Changement de tri |