Skip to content

Commit

Permalink
feat: add sticky table header
Browse files Browse the repository at this point in the history
reverts 8a555fe to add support for
sticky heading. this is added through an optional prop, and exposing a
css variable to be able to set the background color of the head. this
defaults to the Jøkul background color
  • Loading branch information
Jo Emil Holen committed Nov 30, 2022
1 parent 63eaa51 commit 604bfd0
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 2 deletions.
1 change: 1 addition & 0 deletions doc-utils/ComponentExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Props {
choiceProps?: Array<ChoiceProp>;
};
codeExample?: CodeExample;
style?: React.CSSProperties;
}

export const ComponentExample: FC<Props> = ({ component, ...rest }) => {
Expand Down
4 changes: 3 additions & 1 deletion doc-utils/ExampleBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface Props {
choiceProps?: Array<ChoiceProp>;
};
codeExample?: CodeExample;
style?: React.CSSProperties;
}

function useLocalStorage<T>(key: string, defaultValue: T): [T, (newValue: T) => void] {
Expand Down Expand Up @@ -46,7 +47,7 @@ function useLocalStorage<T>(key: string, defaultValue: T): [T, (newValue: T) =>
return [state, setState];
}

export const ExampleBase: FC<Props> = ({ component, knobs, title = "Komponent", codeExample, scrollable }) => {
export const ExampleBase: FC<Props> = ({ component, knobs, title = "Komponent", codeExample, scrollable, style }) => {
const uid = useId("example");
const [theme, setTheme] = useLocalStorage<ColorScheme>("jkl-example-theme", "light");
const [density, setDensity] = useLocalStorage<Density>("jkl-example-density", "comfortable");
Expand Down Expand Up @@ -96,6 +97,7 @@ export const ExampleBase: FC<Props> = ({ component, knobs, title = "Komponent",
} ${scrollable ? "jkl-portal-component-example__example-wrapper--scrollable" : ""} ${
density === "comfortable" ? "jkl-body" : ""
} ${density === "compact" ? "jkl-small" : ""}`.trim()}
style={style}
>
{example}
</div>
Expand Down
8 changes: 8 additions & 0 deletions packages/table-react/documentation/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import "../../table/table.scss";
import "../../button/button.scss";
import "../../icons/animated-icons.scss";
import "../../expand-button/expand-button.scss";
import StickyTableExample, { stickyTableExampleCode } from "./StickyTableExample";

export default function Example() {
return (
Expand Down Expand Up @@ -69,6 +70,13 @@ export default function Example() {
knobs={expandableTableExampleKnobs}
codeExample={expandableTableExampleCode}
/>
<DevExample
style={{ height: "200px" }}
scrollable={true}
title="Tabell med sticky header"
component={StickyTableExample}
codeExample={stickyTableExampleCode}
/>
</>
);
}
88 changes: 88 additions & 0 deletions packages/table-react/documentation/StickyTableExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { FC } from "react";
import { ExampleComponentProps } from "../../../doc-utils";
import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "../src";

const columns = ["Dato", "Saksnummer", "Kundenummer", "Kundenavn", "Milepæl", "Følger saken"];

const rows = [
["24.02.2020", "20-1234567", "010203 99887", "Ola Nordmann", "Opprettet", "Siri Saksbehandler"],
["13.04.2019", "20-8382811", "010203 99887", "Kari Nordkvinne", "Opprettet", "Siri Saksbehandler"],
["31.07.2017", "20-1111", "010203 99887", "Kari Nordkvinne", "Opprettet", "Per Persen"],
["24.02.2020", "20-1234567", "010203 99887", "Ola Nordmann", "Opprettet", "Siri Saksbehandler"],
["13.04.2019", "20-8382811", "010203 99887", "Kari Nordkvinne", "Opprettet", "Siri Saksbehandler"],
["31.07.2017", "20-1111", "010203 99887", "Kari Nordkvinne", "Opprettet", "Per Persen"],
["24.02.2020", "20-1234567", "010203 99887", "Ola Nordmann", "Opprettet", "Siri Saksbehandler"],
["13.04.2019", "20-8382811", "010203 99887", "Kari Nordkvinne", "Opprettet", "Siri Saksbehandler"],
["31.07.2017", "20-1111", "010203 99887", "Kari Nordkvinne", "Opprettet", "Per Persen"],
["24.02.2020", "20-1234567", "010203 99887", "Ola Nordmann", "Opprettet", "Siri Saksbehandler"],
["13.04.2019", "20-8382811", "010203 99887", "Kari Nordkvinne", "Opprettet", "Siri Saksbehandler"],
["31.07.2017", "20-1111", "010203 99887", "Kari Nordkvinne", "Opprettet", "Per Persen"],
];

const StickyTableExample: FC<ExampleComponentProps> = ({ boolValues, choiceValues }) => {
const headless = boolValues?.["Skjul overskrift"];
const type = choiceValues?.["Mobilvisning"];
const props = type === "Liste" ? { "data-collapse": "true", collapseToList: true } : {};

return (
<Table fullWidth {...props} style={{ height: "100px" }}>
<TableCaption srOnly>Overskrift for skjermlesere</TableCaption>
<TableHead srOnly={headless} sticky>
<TableRow>
{columns.map((column, index) => (
<TableHeader key={index} density="compact" 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={[1, 2].includes(cellIndex) ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
);
};

export default StickyTableExample;

export const stickyTableExampleCode = ({ boolValues, choiceValues }: ExampleComponentProps): string => `
<Table fullWidth collapseToList={${choiceValues?.["Mobilvisning"] === "Liste"}}>
<TableCaption srOnly>Overskrift for skjermlesere</TableCaption>
<TableHead srOnly={${boolValues?.["Skjul overskrift"]}}>
<TableRow>
{columns.map((header, index) => (
<TableHeader key={index} density="compact" bold>
{header}
</TableHeader>
))}
</TableRow>
</TableHead>
<TableBody>
{rows.map((row, rowIndex) => (
<TableRow key={rowIndex}>
{row.map((cell, cellIndex) => (
<TableCell
key={cellIndex}
data-th={columns[cellIndex]}
align={[1, 2].includes(cellIndex) ? "right" : "left"}
>
{cell}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</Table>
`;
4 changes: 3 additions & 1 deletion packages/table-react/src/TableHead.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@ import { TableSectionContextProvider } from "./tableSectionContext";

export interface TableHeadProps extends HTMLAttributes<HTMLTableSectionElement> {
srOnly?: boolean;
sticky?: boolean;
}

const TableHead = forwardRef<HTMLTableSectionElement, TableHeadProps>(({ className, srOnly, ...rest }, ref) => {
const TableHead = forwardRef<HTMLTableSectionElement, TableHeadProps>(({ className, srOnly, sticky, ...rest }, ref) => {
return (
<TableSectionContextProvider state={{ isTableHead: true, isTableBody: false, isTableFooter: false }}>
<thead
className={cx("jkl-table-head", className, {
["jkl-table-head--sr-only"]: srOnly,
["jkl-table-head--sticky"]: sticky,
})}
{...rest}
ref={ref}
Expand Down
17 changes: 17 additions & 0 deletions packages/table/_table-head.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
@use "~@fremtind/jkl-core/jkl";

@include jkl.light-mode-variables {
--jkl-table-head-sticky-color: var(--jkl-background-color);
}

@include jkl.dark-mode-variables {
--jkl-table-head-sticky-color: var(--jkl-background-color);
}

.jkl-table-head {
&--sr-only {
@include jkl.screenreader-only;
}

&--sticky {
& > .jkl-table-row {
position: sticky;
top: 0;
z-index: 1;
background-color: var(--jkl-table-head-sticky-color);
}
}
}

0 comments on commit 604bfd0

Please sign in to comment.