Table

Tabell for systematisk visning av data.

Komponenten er klar til testing, men ikke ferdig

Komponenten har blitt utarbeidet nok til at det ikke kommer store endringer, men trenger å bli testet for å avdekke behov. Gi tilbakemelding om noe lugger eller mangler.

Breaking changes varsles i endringsloggen som patches, ikke som major oppdateringer, for å unngå versjonsinflasjon.

Send innspill

Test props


Eksempler

Enkel tabell

Tabell med caption. padding og font-size skalerer ned med breakpoints.

<Table>
  <TableCaption>Våre ladeabonnementer.</TableCaption>
  <TableThead>
    <TableTr>
      <TableTh>Abonnement</TableTh>
      <TableTh>kWt per måned</TableTh>
      <TableTh>Pris per måned</TableTh>
    </TableTr>
  </TableThead>
  <TableTbody>
    <TableTr>
      <TableTd>Liten</TableTd>
      <TableTd>50 kWt</TableTd>
      <TableTd isNumeric>249,-</TableTd>
    </TableTr>
    <TableTr>
      <TableTd>Middels</TableTd>
      <TableTd>85 kWt</TableTd>
      <TableTd isNumeric>299,-</TableTd>
    </TableTr>
    <TableTr>
      <TableTd>Stor</TableTd>
      <TableTd>135 kWt</TableTd>
      <TableTd isNumeric>399,-</TableTd>
    </TableTr>
  </TableTbody>
</Table>

Datatabell

function DataTable() {
  const [selectedRows, setSelectedRows] = React.useState(new Set());

  const setSelectedIndex = (selected, index) => {
    if (selected) {
      setSelectedRows((prev) => new Set([...prev, index]));
    } else {
      setSelectedRows((prev) => new Set([...prev].filter((i) => i !== index)));
    }
  };

  return (
    <Table variant="data">
      <TableThead>
        <TableTr>
          <TableTh>
            <Checkbox
              label="test"
              hideLabel
              checked={
                selectedRows.size === 3
                  ? true
                  : selectedRows.size === 0
                    ? false
                    : "indeterminate"
              }
              onCheckedChange={(selected) => {
                if (selected) {
                  setSelectedRows(new Set([0, 1, 2]));
                } else {
                  setSelectedRows(new Set());
                }
              }}
            />
          </TableTh>
          <TableTh>Abonnement</TableTh>
          <TableTh>kWt per måned</TableTh>
          <TableTh>Pris per måned</TableTh>
        </TableTr>
      </TableThead>
      <TableTbody>
        <TableTr selected={selectedRows.has(0)}>
          <TableTd>
            <Checkbox
              label="test"
              hideLabel
              checked={selectedRows.has(0)}
              onCheckedChange={(selected) => {
                setSelectedIndex(selected, 0);
              }}
            />
          </TableTd>
          <TableTd>Liten</TableTd>
          <TableTd>50 kWt</TableTd>
          <TableTd isNumeric>249,-</TableTd>
        </TableTr>
        <TableTr selected={selectedRows.has(1)}>
          <TableTd>
            <Checkbox
              label="test"
              hideLabel
              checked={selectedRows.has(1)}
              onCheckedChange={(selected) => {
                setSelectedIndex(selected, 1);
              }}
            />
          </TableTd>
          <TableTd>Middels</TableTd>
          <TableTd>85 kWt</TableTd>
          <TableTd isNumeric>299,-</TableTd>
        </TableTr>
        <TableTr selected={selectedRows.has(2)}>
          <TableTd>
            <Checkbox
              label="test"
              hideLabel
              checked={selectedRows.has(2)}
              onCheckedChange={(selected) => {
                setSelectedIndex(selected, 2);
              }}
            />
          </TableTd>
          <TableTd>Stor</TableTd>
          <TableTd>135 kWt</TableTd>
          <TableTd isNumeric>399,-</TableTd>
        </TableTr>
      </TableTbody>
    </Table>
  );
}

Datatabell med sortering

function DataTable() {
  const data = [
    {
      id: 1,
      ikkeSort: "Test",
      abb: "Liten",
      kWhMnd: "1 kWh",
      prisMnd: "249,-"
    },
    {
      id: 2,
      ikkeSort: "Test2",
      abb: "Middels",
      kWhMnd: "2 kWh",
      prisMnd: "299,-"
    },
    {
      id: 3,
      ikkeSort: "Test3",
      abb: "Stor",
      kWhMnd: "3 kWh",
      prisMnd: "399,-"
    },
  ]

  const [sort, setSort] = React.useState({});
  
  const onSortChange = (col) => {
    if (sort) {
      if (sort.col === col) {
        if (sort.dir === "asc"){
          setSort({ col, dir: "desc" });
        }
        else if (sort.dir === "desc") {
          setSort({});
        } else {
          setSort({ col, dir: "asc" })
        }
      } else {
        setSort({ col, dir: "asc" })
      }
    }
  }
  
  const sortedData = sort.col ? data.sort((a,b) => {
    if (sort.dir === "asc") {
      return a[sort.col].localeCompare(b[sort.col])
    } else {
      return -1 * a[sort.col].localeCompare(b[sort.col])
    }
  }) : data;
  
  return (
    <Table variant="data">
      <TableThead>
        <TableTr>
          <TableTh>Ikkesort</TableTh>
          <TableTh canSort isSorted={sort.col === "abb" ? sort.dir : false} onSort={() => onSortChange("abb")}>Abonnement</TableTh>
          <TableTh canSort isSorted={sort.col === "kWhMnd" ? sort.dir : false} onSort={() => onSortChange("kWhMnd")}>kWt per måned</TableTh>
          <TableTh canSort isSorted={sort.col === "prisMnd" ? sort.dir : false} onSort={() => onSortChange("prisMnd")}>Pris per måned</TableTh>
        </TableTr>
      </TableThead>
      <TableTbody>
        {
          sortedData.map((d) => (
            <TableTr key={d.id}>
              <TableTd>{d.ikkeSort}</TableTd>
              <TableTd>{d.abb}</TableTd>
              <TableTd>{d.kWhMnd}</TableTd>
              <TableTd isNumeric>{d.prisMnd}</TableTd>
            </TableTr>
          ))
        }
      </TableTbody>
    </Table>
  );
}

Retningslinjer

UU-tilsynet har en flott artikkel om bruk av tabeller. Her er noen tips:

Tabeller skal utelukkende brukes til å presentere data, og ikke for å styre utseende. Riktig bruk av tabeller er avgjørende for at informasjonen blir tolket riktig av hjelpemiddel og brukeren klarer å tolke informasjonen.

Hvis tabellen har en tittel, skal du bruke <caption> for å definere tittelen og gi en overordnet beskrivelse av hva tabellen presenterer.

Bruk overskriftceller <th> så dataceller <td> blir koblet med riktig rad- og overskrift. Om det også er overskrifter horisontalt, bruk scope for å markere retning på data.

Andre tips er å gjøre innholdet så leselig som mulig. Det kan du gjøre ved å dele opp i flere tabeller eller å skape god nok avstand i kolonnene.

Kode

<Table />

import { Table } from "@aneo-org/design-react/serverComponents";

Rot-tabellen.

PropTypeBeskrivelse
childrenReactNodeInnhold i elementet

<TableCaption />

import { TableCaption } from "@aneo-org/design-react/serverComponents";

Valgfri tittel for tabellen.

PropTypeBeskrivelse
childrenReactNodeInnhold

<TableThead />

import { TableThead } from "@aneo-org/design-react/serverComponents";

Beholder for tabellens header-celler.

<TableTr />

import { TableTr } from "@aneo-org/design-react/serverComponents";

Rad i tabellen. Tilsvarende <tr>.

PropTypeBeskrivelse
selected?booleanKun relevant for dataTable. Brukes for å markere en rad som valgt.

<TableTh />

import { TableTh } from "@aneo-org/design-react/serverComponents";

Header-celle.

PropTypeBeskrivelse
canSort?booleanBruk dersom tabellen skal kunne sorteres.
isSorted?"asc" | "desc" | falseValgfri. Sorteringsrekkefølgen til kolonnen.
onSort?(event: unknown) => voidCallback-funksjon som kalles når bruker trykker på sorteringsknappen for å sortere kolonnen.
childrenReact.ReactNodeInnholdet i cellen.

<TableTd />

import { TableTd } from "@aneo-org/design-react/serverComponents";

Vanlig celle.

PropTypeBeskrivelse
isNumeric?booleanBruk dersom verdien i cellen er et tall. Innholdet vil da bli høyrejustert og tallet vises på riktig måte.