Hopp til innhold

Table

Vi bruker tabeller for å vise data på en ordnet måte som gjør sammenlikning enkelt.

Kom i gang

Installer
npm i @fremtind/jkl-table-react
# Eller installer stilpakken hvis du kun skal bruke CSS/Sass
npm i @fremtind/jkl-table
Bruk
// importer komponentene du trenger for å bygge tabellen din
// se React API nederst på siden for full oversikt
import { Table, TableRow, TableCell } from "@fremtind/jkl-table-react";
// importer stilark via JavaScript med CSS-loader
import "@fremtind/jkl-table/table.min.css";
// for ekspanderende rader trenger du også
import "@fremtind/jkl-icons/icons.min.css";
import "@fremtind/jkl-icon-button/icon-button.min.css";
import "@fremtind/jkl-expand-button/expand-button.min.css";
// for paginering trenger du også
import "@fremtind/jkl-text-input/text-input.min.css";
import "@fremtind/jkl-select/select.min.css";
// du kan også importere stilark via SCSS
@use "@fremtind/jkl-table/table"
React
Versjon
Dokumentasjon
Readme
Changelog
Migration

Live demo

Table
Egenskaper
Variant
Mobilvisning
Visning
Tema
Tetthet
const variant = 'standard';
const type = 'table';
const props =
type === "list" ? { "data-collapse": "true", collapseToList: true } : {};
const columns = tableData.columns;
const rows = tableData.rows.slice(0, 5);
if (variant === "action") {
return (
<div
style={{
maxWidth: "100%",
}}
>
<Table fullWidth {...props}>
<TableCaption srOnly>Tabell med handlinger</TableCaption>
<TableHead srOnly={false}>
<TableRow>
{columns.map((column, columnIndex) => (
<TableHeader
align={columnIndex === 3 ? "right" : "left"}
key={column}
bold
>
{column}
</TableHeader>
))}
<TableHeader srOnly>Dokument</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
verticalAlign="center"
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
<TableCell
align="right"
data-th="Dokument"
verticalAlign="center"
>
<SecondaryButton onClick={(e) => console.log(e)}>
Åpne
</SecondaryButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
} else if (variant === "clickable") {
return (
<div
style={{
maxWidth: "100%",
}}
>
<Table fullWidth {...props}>
<TableCaption srOnly>Tabell med klikkbare rader</TableCaption>
<TableHead srOnly={false}>
<TableRow>
{columns.map((column, columnIndex) => (
<TableHeader
align={columnIndex === 3 ? "right" : "left"}
key={column}
bold
>
{column}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow
key={rowIndex}
clickable={{ onClick: (e) => console.log(e) }}
>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
);
} else if (variant === "standard") {
return (
<div
style={{
maxWidth: "100%",
}}
>
<Table fullWidth {...props}>
<TableCaption srOnly>Overskrift for skjermlesere</TableCaption>
<TableHead srOnly={false}>
<TableRow>
{columns.map((column, columnIndex) => (
<TableHeader
align={columnIndex === 3 ? "right" : "left"}
key={column}
bold
>
{column}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}

Rader med handling

Table, rader med handling
Visning
Tema
Tetthet
const columns = tableData.columns;
const rows = tableData.rows.slice(0, 5);
return (
<div
style={{
maxWidth: "100%",
overflowX: "scroll",
}}
>
<Table fullWidth>
<TableCaption srOnly>Tabell med handling</TableCaption>
<TableHead>
<TableRow>
{columns.map((column) => (
<TableHeader key={column} bold>
{column}
</TableHeader>
))}
<TableHeader srOnly>Dokument</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
verticalAlign="center"
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
<TableCell align="right" data-th="Dokument" verticalAlign="center">
<SecondaryButton onClick={(e) => console.log(e)}>
Åpne
</SecondaryButton>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);

Klikkbare rader

Table, klikkbare rader
Visning
Tema
Tetthet
const columns = tableData.columns;
const rows = tableData.rows.slice(0, 5);
return (
<div
style={{
maxWidth: "100%",
overflowX: "scroll",
}}
>
<Table fullWidth>
<TableCaption srOnly>Tabell med klikkbare rader</TableCaption>
<TableHead>
<TableRow>
{columns.map((column) => (
<TableHeader key={column} bold>
{column}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow
key={rowIndex}
clickable={{ onClick: (e) => console.log(e) }}
>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
);

Ekspanderende tabeller

Table, ekspanderende rader
Visning
Tema
Tetthet
const columns = tableData.columns;
const rows = tableData.rows.slice(0, 5);
return (
<div
style={{
maxWidth: "100%",
overflowX: "scroll",
}}
>
<Table fullWidth collapseToList={false}>
<TableCaption srOnly>Tabell med ekspanderbare rader</TableCaption>
<TableHead>
<TableRow>
{columns.map((column) => (
<TableHeader key={column} bold>
{column}
</TableHeader>
))}
<TableHeader srOnly>Vis mer</TableHeader>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<ExpandableTableRow
key={rowIndex}
expandedChildren={
<Table fullWidth>
<TableBody>
<TableRow>
<TableCell>Hello, world!</TableCell>
</TableRow>
</TableBody>
</Table>
}
>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
verticalAlign="center"
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
<ExpandableTableRowController
data-th="Mer informasjon"
verticalAlign="center"
>
Mer informasjon
</ExpandableTableRowController>
</ExpandableTableRow>
))}
</TableBody>
</Table>
</div>
);

Sticky tabellheading

Table, med sticky overskrift
Visning
Tema
Tetthet
const columns = tableData.columns;
const rows = tableData.rows.slice(0, 5);
return (
<div
style={{
maxWidth: "100%",
overflowX: "scroll",
height: "200px",
}}
>
<Table fullWidth>
<TableCaption srOnly>Overskrift for skjermlesere</TableCaption>
<TableHead sticky>
<TableRow>
{columns.map((column, index) => (
<TableHeader key={index} bold>
{column}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
);

Paginering

Table, med paginering
Visning
Tema
Tetthet
const columns = tableData.columns;
const rows = tableData.rows;
const ref = React.useRef(null);
const [activePage, setActivePage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10);
const startIndex = activePage * rowsPerPage;
const visibleRows = rows.slice(startIndex, startIndex + rowsPerPage);
return (
<Table ref={ref} fullWidth>
<TableCaption srOnly>Overskrift for skjermlesere</TableCaption>
<TableHead>
<TableRow>
{columns.map((header, index) => (
<TableHeader key={index} bold>
{header}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{visibleRows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={5}>
<TablePagination
activePage={activePage}
totalNumberOfRows={rows.length}
rowsPerPage={rowsPerPage}
rowsPerPageItems={[
10,
25,
50,
100,
150,
{ label: "Alle", value: -1 },
]}
onChangeRowsPerPage={(e) => {
const newRowsPerPage = Number.parseInt(e.target.value);
setRowsPerPage(newRowsPerPage);
setActivePage(0);
if (ref.current) {
ref.current.scrollIntoView({
behavior: "smooth",
});
}
}}
onChange={(_, toPage) => {
setActivePage(toPage);
if (ref.current) {
ref.current.scrollIntoView({
behavior: "smooth",
});
}
}}
withGoToPage
/>
</TableCell>
</TableRow>
</TableFooter>
</Table>
);
return (
<div
style={{
maxWidth: "100%",
overflowX: "scroll",
height: "200px",
}}
>
<Table fullWidth>
<TableCaption srOnly>Overskrift for skjermlesere</TableCaption>
<TableHead sticky>
<TableRow>
{columns.map((column, index) => (
<TableHeader key={index} bold>
{column}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
</div>
);

Sortering

Table, med sorterbare kolonner
Visning
Tema
Tetthet
const columns = tableData.columns;
const rows = tableData.rows.slice(0, 5);
const [sortBy, setSortBy] = React.useState(columns[0]);
const [direction, setDirection] = React.useState("desc");
const handleSortChange = (sortKey, sortDirection) => {
setSortBy(sortKey);
setDirection(sortDirection);
};
const { getSortProps } = useSortableTableHeader(
sortBy,
direction,
handleSortChange
);
console.log({ sortBy, direction });
console.log(
rows.sort((a, b) => {
const valA = a[columns.indexOf(sortBy)];
const valB = b[columns.indexOf(sortBy)];
if (valA === valB) return 0;
if (valA > valB) return direction === "desc" ? -1 : 1;
})
);
return (
<Table fullWidth>
<TableCaption srOnly>Overskrift for skjermlesere</TableCaption>
<TableHead>
<TableRow>
{columns.map((header, index) => (
<TableHeader key={index} bold {...getSortProps(header)}>
{header}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows
.sort((a, b) => {
const valA = a[sortBy];
const valB = b[sortBy];
if (valA === valB) return 0;
if (valA > valB) return sortDirection === "desc" ? 1 : -1;
})
.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
align={cellIndex === 3 ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
);

React API

Her finner du en oversikt over props på komponentene i pakken.