Skip to content

Commit

Permalink
feat(DsfrDataTable): ✨ permet de sélectionner les colonnes triables
Browse files Browse the repository at this point in the history
  • Loading branch information
laruiss committed Sep 4, 2024
1 parent 7620472 commit 8da2d8b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
43 changes: 37 additions & 6 deletions src/components/DsfrDataTable/DsfrDataTable.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ Le composant `DsfrDataTable` est un élément puissant et polyvalent pour affich

🏅 La documentation sur le tableau sur le [DSFR](https://www.systeme-de-design.gouv.fr/elements-d-interface/composants/tableau/)

<VIcon name="vi-file-type-storybook" /> La story sur le tableau sur le storybook de [VueDsfr](https://storybook.vue-ds.fr/?path=/docs/composants-dsfrdatatable--docs)
<VIcon name="vi-file-type-storybook" /> La story sur le tableau de données sur le storybook de [VueDsfr](https://storybook.vue-ds.fr/?path=/docs/composants-dsfrdatatable--docs)

## 📐 Structure

Le composant `DsfrDataTable` s'utilise pour afficher des données structurées sous forme de tableau. Il prend en charge le tri des colonnes, la pagination des lignes, et l'ajout de boutons ou d'icônes pour effectuer des actions spécifiques sur les données.

## Props 🛠️

Expand All @@ -17,18 +21,45 @@ Le composant `DsfrDataTable` est un élément puissant et polyvalent pour affich
| `rows` | `Array<DsfrDataTableRowProps \| string[] \| DsfrDataTableCellProps[]>` | `[]` | | Les données de chaque rangée dans le tableau. |
| `rowKey` | `string \| Function` | `undefined`| | Une clé unique pour chaque rangée, utilisée pour optimiser la mise à jour du DOM. |
| `currentPage` | `number` | `1` | | La page actuelle dans la pagination du tableau. |
| `resultsDisplayed`| `number` | `10` | | Le nombre de résultats affichés par page dans la pagination. |
| `selectableRows` | `boolean` | `false` | Si `true`, permet la sélection des lignes via des cases à cocher. |
| `sortableRows` | `boolean \| string[]` | `false` | Si `true`, permet le tri des lignes selon chaque colonne du header. Peut être un tableau de clés pour spécifier les colonnes triables. |
| `sorted` | `string` | **Obligatoire** | Clé de la colonne actuellement triée. |
| `sortFn` | `(a: unknown, b: unknown) => number` | `defaultSortFn` | Fonction de tri personnalisée pour les lignes du tableau. |
| `verticalBorders` | `boolean` | `false` | Si `true`, affiche des bordures verticales entre les colonnes. |
| `bottomCaption` | `boolean` | `false` | Si `true`, affiche une légende en bas du tableau. |
| `noCaption` | `boolean` | `false` | Si `true`, supprime la légende du tableau. |
| `pages` | `Page[]` | `undefined` | Liste des pages pour la pagination. Si non définie, les pages sont générées automatiquement. |
| `pagination` | `boolean` | `false` | Si `true`, active la pagination des lignes du tableau. |
| `paginationOptions` | `number[]` | `[5, 10, 20]` | Options disponibles pour le nombre de lignes par page. |
| `currentPage` | `number` | `1` | Numéro de la page actuellement affichée. |
| `rowsPerPage` | `number` | `10` | Nombre de lignes à afficher par page. |
| `bottomActionBarClass` | `string \| Record<string, boolean> \| string[]` | `undefined` | Classe CSS pour la barre d'actions en bas du tableau. |
| `paginationWrapperClass` | `string \| Record<string, boolean> \| string[]` | `undefined` | Classe CSS pour l'élément englobant la pagination. |

## Events 📡

| Nom | Description |
|----------------------|-------------------------------------------------|
| `update:currentPage` | Émis lors du changement de la page actuelle. |
| Nom | Payload | Description |
|----------------------|---------|----------------------------------------|
| `update:current-page` | | Émis lors du changement du numéro de page (dans le composant pagination intégré). |
| `update:rows-per-page` | | Émis lors du changement du nombre de lignes à afficher par page (dans le composant pagination intégré). |
| `update:selection` | | Émis lors du changement de la sélection de lignes. |
| `update:sorted-by` | | Émis lors du changement de l’identifiant de la colonne à trier. |
| `update:sorted-desc` | | Émis lors du changement du sens de tri. |

Vous pouvez donc utiliser `v-model` pour :

- selection
- rowsPerPage
- currentPage
- sortedBy
- sortedDesc

## 🧩 Slots

- **`header`**: Ce slot permet de personnaliser les en-têtes du tableau. Par défaut, il utilise [`DsfrDataTableHeaders`](./DsfrDataTableHeader.md) avec les props `headers`.
- **Slot par défaut**: Utilisé pour le corps du tableau. Par défaut, il affiche les rangées de données via `DsfrDataTableRow`.
- **`header`** : Permet de personnaliser le rendu des en-têtes de colonne.
- **`cell`** : Permet de personnaliser le contenu des cellules.
- **`pagination`** : Permet de personnaliser la pagination affichée sous le tableau.

## Exemples 📝

Expand Down
22 changes: 11 additions & 11 deletions src/components/DsfrDataTable/DsfrDataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export type DsfrDataTableProps = {
topActionsRow?: string[]
bottomActionsRow?: string[]
selectableRows?: boolean
sortableRows?: boolean
sortableRows?: boolean | string[]
sorted: string
sortFn?: (a: unknown, b: unknown) => number
verticalBorders?: boolean
Expand Down Expand Up @@ -75,26 +75,26 @@ function defaultSortFn (a, b) {
return 0
}
const sorted = defineModel<string | undefined>('sorted', { default: undefined })
const sortedBy = defineModel<string | undefined>('sortedBy', { default: undefined })
const sortedDesc = defineModel('sortedDesc', { default: false })
function sortBy (key: string) {
if (!props.sortableRows) {
if (!props.sortableRows || (Array.isArray(props.sortableRows) && !props.sortableRows.includes(key))) {
return
}
if (sorted.value === key) {
if (sortedBy.value === key) {
if (sortedDesc.value) {
sorted.value = undefined
sortedBy.value = undefined
sortedDesc.value = false
return
}
sortedDesc.value = true
return
}
sortedDesc.value = false
sorted.value = key
sortedBy.value = key
}
const sortedRows = computed(() => {
const _sortedRows = sorted.value ? props.rows.slice().sort(props.sortFn ?? defaultSortFn) : props.rows.slice()
const _sortedRows = sortedBy.value ? props.rows.slice().sort(props.sortFn ?? defaultSortFn) : props.rows.slice()
if (sortedDesc.value) {
_sortedRows.reverse()
}
Expand Down Expand Up @@ -140,7 +140,7 @@ function onPaginationOptionsChange () {
selection.value.length = 0
}
function copyToClipboard (text) {
function copyToClipboard (text: string) {
navigator.clipboard.writeText(text)
}
</script>
Expand Down Expand Up @@ -190,21 +190,21 @@ function copyToClipboard (text) {
@keydown.space="sortBy((header as DsfrDataTableHeaderCellObject).key ?? header)"
>
<div
:class="{ 'sortable-header': sortableRows }"
:class="{ 'sortable-header': sortableRows === true || (Array.isArray(sortableRows) && sortableRows.includes((header as DsfrDataTableHeaderCellObject).key ?? header)) }"
>
<slot
name="header"
v-bind="typeof header === 'object' ? header : { key: header, label: header }"
>
{{ typeof header === 'object' ? header.label : header }}
</slot>
<span v-if="sorted !== ((header as DsfrDataTableHeaderCellObject).key ?? header) && sortableRows">
<span v-if="sortedBy !== ((header as DsfrDataTableHeaderCellObject).key ?? header) && (sortableRows === true || (Array.isArray(sortableRows) && sortableRows.includes((header as DsfrDataTableHeaderCellObject).key ?? header)))">
<VIcon
name="ri-sort-asc"
color="var(--grey-625-425)"
/>
</span>
<span v-else-if="sorted === ((header as DsfrDataTableHeaderCellObject).key ?? header)">
<span v-else-if="sortedBy === ((header as DsfrDataTableHeaderCellObject).key ?? header)">
<VIcon :name="sortedDesc ? 'ri-sort-desc' : 'ri-sort-asc'" />
</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const currentPage = ref<number>(0)
bottom-action-bar-class="bottom-action-bar-class"
pagination-wrapper-class="pagination-wrapper-class"
sorted="id"
sortable-rows
:sortable-rows="['id']"
>
<template #header="{ label }">
<em>{{ label }}</em>
Expand Down

0 comments on commit 8da2d8b

Please sign in to comment.