Skip to content

Ligne de tableau - DsfrTableRow

Rencontrez DsfrTableRow, le composant incontournable pour structurer les lignes de votre tableau Vue avec style et efficacité. Parfait pour organiser les données et les présenter de manière claire, ce composant est un véritable atout dans votre boîte à outils de développeur.

🛠️ Props

NomTypeDéfautObligatoireDescription
rowDataArray[]Les données pour chaque cellule de la rangée.
rowAttrsObject{}Les attributs HTML supplémentaires pour l'élément <tr>.

Description des Types

  • rowData: Un tableau contenant les données de chaque cellule. Chaque élément peut être une chaîne ou un objet avec des propriétés supplémentaires pour la cellule.
  • rowAttrs: Un objet représentant des attributs HTML supplémentaires, comme des classes ou des styles, à appliquer sur la rangée.

🧩 Slots

  • Slot par défaut: Utilisé pour insérer du contenu personnalisé dans la rangée du tableau, avant les cellules générées automatiquement.

📝 Exemples

Exemple basique

vue
<DsfrTableRow :rowData="['Alice', 30, 'Paris']" />

Exemple avec attributs de ligne (row)

vue
<DsfrTableRow
  :rowData="['Bob', 24, 'Lyon']"
  :rowAttrs="{ class: 'highlighted-row', id: 'row-bob' }"
/>

Exemple complexe

vue
<script lang="ts" setup>
import { getCurrentInstance } from 'vue'

import DsfrTag from '../../DsfrTag/DsfrTag.vue'
import DsfrTable from '../DsfrTable.vue'
import DsfrTableRow from '../DsfrTableRow.vue'

getCurrentInstance()?.appContext.app.component('DsfrTag', DsfrTag)

const title = 'Utilisateurs'
const headers = ['Nom', 'Prénom', 'Email', 'Statut']
const complexRowData = {
  rowAttrs: {
    class: 'pointer',
    style: 'text-decoration: line-through',
  },
  rowData: [
    'EGAUD',
    'Pierre-Louis',
    'pierre.egaud@ninja.com',
    {
      component: 'DsfrTag',
      label: 'Supprimé',
      class: 'error',
    },
  ],
}
</script>

<template>
  <DsfrTable
    :title="title"
    :headers="headers"
  >
    <DsfrTableRow
      :row-data="complexRowData.rowData"
      :row-attrs="complexRowData.rowAttrs"
    />
  </DsfrTable>
</template>

<style scoped>
.pointer {
  cursor: pointer;
}
:deep(.error) {
  color: var(--error-425-625);
  background-color: var(--error-950-100);
}
</style>

⚙️ Code source du composant

vue
<script lang="ts" setup>
import DsfrTableCell from './DsfrTableCell.vue'
import type { DsfrTableRowProps } from './DsfrTable.types'

export type { DsfrTableRowProps }

withDefaults(defineProps<DsfrTableRowProps>(), {
  rowData: () => [],
  rowAttrs: () => ({}),
})
</script>

<template>
  <tr v-bind="rowAttrs">
    <!-- @slot Slot par défaut pour le contenu d’une ligne de tableau -->
    <slot />
    <DsfrTableCell
      v-for="(cell, i) of rowData"
      :key="i"
      :field="cell ?? ''"
      :cell-attrs="(typeof cell === 'object' && cell !== null && !cell.component) ? cell.cellAttrs : {}"
    />
  </tr>
</template>
ts
import type { HTMLAttributes, TdHTMLAttributes, ThHTMLAttributes } from 'vue'

import type VIcon from '../VIcon/VIcon.vue'

export type DsfrTableRowProps = {
  rowData?: (string | Record<string, any>)[]
  rowAttrs?: HTMLAttributes
}

export type DsfrTableHeaderProps = {
  header?: string
  headerAttrs?: ThHTMLAttributes & { onClick?: (e: MouseEvent) => void }
  icon?: string | InstanceType<typeof VIcon>['$props']
}

export type DsfrTableHeadersProps = (string | (DsfrTableHeaderProps & { text?: string }))[]

export type DsfrTableCellProps = {
  field: string | Record<string, unknown>
  cellAttrs?: TdHTMLAttributes
  component?: string
  text?: string
  title?: string
  class?: string
  onClick?: Promise<void>
}

export type DsfrTableProps = {
  title: string
  headers?: DsfrTableHeadersProps
  rows?: (DsfrTableRowProps | (DsfrTableCellProps | { component: string, [k: string]: unknown } | string)[])[]

  rowKey?: ((row: (string | Record<string, any>)[] | undefined) => string | number | symbol | undefined) | string
  noCaption?: boolean
  pagination?: boolean
  currentPage?: number
  resultsDisplayed?: number
}

Voilà ! DsfrTableRow est prêt à transformer vos données en un tableau visuellement attrayant et fonctionnel.