Compare commits

..
Author SHA1 Message Date
github-actions[bot] ff454dbc06 Version Packages (#4840)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-28 11:07:06 +02:00
Halvor Haugan 92f6d9e93b Add module decleration for ds-css (#4838) 2026-04-27 18:42:22 +02:00
Halvor HauganandCopilot 516634b852 [website] Improvements in props-section (#4839)
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 18:12:34 +02:00
Halvor Haugan 48939bcee0 Merge branch 'main' of github.com:navikt/aksel 2026-04-27 18:11:27 +02:00
KenandCopilot 5ea6069010 🐛 Stop className from being fowarded to input-element in radio/checkbox (#4837)
* 🐛 Stop className from being fowarded to input-element in radio/checkbox

* Update .changeset/cuddly-queens-roll.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-27 18:10:05 +02:00
Halvor Haugan 5eee3136a0 Adjust JSDoc in ModalProps 2026-04-27 18:10:04 +02:00
Ken 21521b892e [DataTable] Default to sticky header always 2026-04-27 14:05:06 +02:00
Ken f563c18a59 [DataTable] Move selection-props to single prop 2026-04-27 13:32:26 +02:00
Ken ca1bd3f5c0 [DataTable] Added 'align'-prop to columnDef 2026-04-27 13:20:54 +02:00
Ken a71f326426 [DataTable] Removed untrue comment 2026-04-27 13:01:23 +02:00
Ken fb79fd775c [DataTable] Fix scroll when defining detailsPanel height 2026-04-27 13:01:23 +02:00
Ken 8a0afad10c [DataTable] Only render loading-label once 2026-04-27 13:01:22 +02:00
Halvor HauganandCopilot 92e6128cc9 DataTable: Add resizable prop + fix resizing issue
Co-authored-by: Copilot <copilot@github.com>
2026-04-27 10:04:30 +02:00
Ken ff0221736c Squashed commit of the following:
commit 82656da435
Author: Ken <ken.aleksander@gmail.com>
Date:   Mon Apr 27 09:57:48 2026 +0200

    📝 Added comments

commit ab9932ed8f
Author: Ken <ken.aleksander@gmail.com>
Date:   Mon Apr 27 09:55:47 2026 +0200

    📝 Added comments

commit 180ca25861
Author: Ken <ken.aleksander@gmail.com>
Date:   Fri Apr 24 13:38:51 2026 +0200

    ⚡ Add cached parser for optimization

commit cbac535fcb
Author: Ken <ken.aleksander@gmail.com>
Date:   Fri Apr 24 13:10:18 2026 +0200

    📝 Add docs

commit 296049b8c7
Author: Ken <ken.aleksander@gmail.com>
Date:   Fri Apr 24 13:00:21 2026 +0200

    [DataTable] Optimize recursive parsing

commit 073d811b3f
Author: Ken <ken.aleksander@gmail.com>
Date:   Fri Apr 24 12:45:15 2026 +0200

    [DataTable] Now supports branch selection

commit da1374e833
Author: Ken <ken.aleksander@gmail.com>
Date:   Fri Apr 24 12:22:41 2026 +0200

    [DataTable] Updated selection
2026-04-27 09:58:45 +02:00
Ken abe4a768e1 🐛 Revert nb locale update 2026-04-24 15:06:30 +02:00
Ken c94d801b45 [DataTable] removed unused tests 2026-04-24 13:42:08 +02:00
34 changed files with 365 additions and 443 deletions

No files matched your search

+2
View File
@@ -1,5 +1,7 @@
# @navikt/aksel-icons
## 8.10.3
## 8.10.2
## 8.10.1
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-icons",
"version": "8.10.2",
"version": "8.10.3",
"author": "Aksel | Nav",
"homepage": "https://aksel.nav.no/ikoner",
"repository": {
+2
View File
@@ -1,5 +1,7 @@
# @navikt/aksel-stylelint
## 8.10.3
## 8.10.2
## 8.10.1
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel-stylelint",
"version": "8.10.2",
"version": "8.10.3",
"type": "module",
"engines": {
"node": ">=18.12.0"
@@ -42,8 +42,8 @@
"dev": "yarn watch:lint"
},
"devDependencies": {
"@navikt/ds-css": "^8.10.2",
"@navikt/ds-tokens": "^8.10.2",
"@navikt/ds-css": "^8.10.3",
"@navikt/ds-tokens": "^8.10.3",
"concurrently": "9.2.1",
"postcss-selector-parser": "^7.1.0",
"postcss-value-parser": "^4.2.0",
+8
View File
@@ -1,5 +1,13 @@
# @navikt/aksel
## 8.10.3
### Patch Changes
- Updated dependencies [[`92f6d9e`](https://github.com/navikt/aksel/commit/92f6d9e93b879962df8415f7fad22203174dd3a8)]:
- @navikt/ds-css@8.10.3
- @navikt/ds-tokens@8.10.3
## 8.10.2
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/aksel",
"version": "8.10.2",
"version": "8.10.3",
"description": "Aksel command line interface. Codemods and other utilities for Aksel users.",
"author": "Aksel | Nav designsystem team",
"license": "MIT",
@@ -40,8 +40,8 @@
"url": "https://github.com/navikt/aksel/issues"
},
"dependencies": {
"@navikt/ds-css": "^8.10.2",
"@navikt/ds-tokens": "^8.10.2",
"@navikt/ds-css": "^8.10.3",
"@navikt/ds-tokens": "^8.10.3",
"chalk": "5.6.2",
"cli-progress": "3.12.0",
"clipboardy": "5.0.1",
+6
View File
@@ -1,5 +1,11 @@
# @navikt/ds-css
## 8.10.3
### Patch Changes
- Add module declaration to avoid TypeScript error when importing ([`92f6d9e`](https://github.com/navikt/aksel/commit/92f6d9e93b879962df8415f7fad22203174dd3a8))
## 8.10.2
### Patch Changes
+12 -7
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-css",
"version": "8.10.2",
"version": "8.10.3",
"description": "CSS for Nav Designsystem",
"author": "Aksel | Nav designsystem team",
"keywords": [
@@ -14,7 +14,8 @@
"files": [
"*",
"!dist/version",
"!config/bundle.js"
"!config/bundle.ts",
"!config/get-version.js"
],
"repository": {
"type": "git",
@@ -30,7 +31,7 @@
"css:get-version": "node config/get-version.js"
},
"devDependencies": {
"@navikt/ds-tokens": "^8.10.2",
"@navikt/ds-tokens": "^8.10.3",
"browserslist": "^4.25.0",
"esbuild": "^0.27.4",
"fast-glob": "3.3.3",
@@ -46,9 +47,13 @@
],
"main": "./dist/index.css",
"exports": {
".": "./dist/index.css",
"./dist/*": "./dist/*",
"./tokens.json": "./tokens.json",
"./config/_mappings": "./config/_mappings.js"
".": {
"types": "./types.d.ts",
"default": "./dist/index.css"
},
"./dist/*": {
"types": "./types.d.ts",
"default": "./dist/*"
}
}
}
+1
View File
@@ -0,0 +1 @@
declare module "@navikt/ds-css" {}
+10
View File
@@ -1,5 +1,15 @@
# @navikt/ds-react
## 8.10.3
### Patch Changes
- Radio, Checkbox: Fix regression where `className` was mistakenly passed to `input`-element ([#4837](https://github.com/navikt/aksel/pull/4837))
- Updated dependencies []:
- @navikt/ds-tokens@8.10.3
- @navikt/aksel-icons@8.10.3
## 8.10.2
### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-react",
"version": "8.10.2",
"version": "8.10.3",
"description": "React components from the Norwegian Labour and Welfare Administration.",
"author": "Aksel, a team part of the Norwegian Labour and Welfare Administration.",
"license": "MIT",
@@ -706,8 +706,8 @@
"dependencies": {
"@floating-ui/react": "0.27.8",
"@floating-ui/react-dom": "^2.1.8",
"@navikt/aksel-icons": "^8.10.2",
"@navikt/ds-tokens": "^8.10.2",
"@navikt/aksel-icons": "^8.10.3",
"@navikt/ds-tokens": "^8.10.3",
"date-fns": "^4.0.0",
"react-day-picker": "9.14.0"
},
@@ -58,7 +58,7 @@ const userColumnDef: ColumnDefinitions<UserDataTest> = [
header: "Id",
label: "Id",
cell: ({ id }) => id,
type: "number",
align: "right",
defaultWidth: "100px",
},
{
@@ -120,8 +120,10 @@ export const ItemsAsDataWithCustomRowId: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={userData}
selectionMode="multiple"
onSelectionChange={console.info}
selection={{
selectionMode: "multiple",
onSelectionChange: console.info,
}}
getRowId={(row) => row.foo + row.bar}
/>
);
@@ -134,8 +136,10 @@ export const SelectionModeMultiple: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={userData}
selectionMode="multiple"
onSelectionChange={console.info}
selection={{
selectionMode: "multiple",
onSelectionChange: console.info,
}}
getRowId={(row) => row.foo + row.bar}
withKeyboardNav
/>
@@ -149,8 +153,10 @@ export const SelectionModeSingle: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={userData}
selectionMode="single"
onSelectionChange={console.info}
selection={{
selectionMode: "multiple",
onSelectionChange: console.info,
}}
getRowId={(row) => row.foo + row.bar}
withKeyboardNav
/>
@@ -164,8 +170,10 @@ export const SelectionModeSingleWithoutKeyboardNav: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={userData}
selectionMode="single"
onSelectionChange={console.info}
selection={{
selectionMode: "multiple",
onSelectionChange: console.info,
}}
getRowId={(row) => row.foo + row.bar}
/>
);
@@ -178,11 +186,13 @@ export const SelectionWithDisabledRows: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={userData}
selectionMode="multiple"
onSelectionChange={console.info}
selection={{
selectionMode: "multiple",
onSelectionChange: console.info,
disabledSelectionKeys: [1, 2],
}}
getRowId={(row) => row.id}
withKeyboardNav
disabledSelectionKeys={[1, 2]}
/>
);
},
@@ -205,9 +215,11 @@ export const ControlledSelection: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={userData}
selectionMode="multiple"
selectedKeys={selectedKeys}
onSelectionChange={setSelectedKeys}
selection={{
selectionMode: "multiple",
onSelectionChange: setSelectedKeys,
selectedKeys,
}}
getRowId={(row) => row.id}
/>
</div>
@@ -221,9 +233,11 @@ export const DefaultSelectedKeys: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={userData}
selectionMode="multiple"
defaultSelectedKeys={[1, 3]}
onSelectionChange={console.info}
selection={{
selectionMode: "multiple",
onSelectionChange: console.info,
defaultSelectedKeys: [1, 3],
}}
getRowId={(row) => row.id}
/>
);
@@ -236,10 +250,12 @@ export const SingleSelectionWithDisabledRows: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={userData}
selectionMode="single"
onSelectionChange={console.info}
selection={{
selectionMode: "multiple",
onSelectionChange: console.info,
disabledSelectionKeys: [2],
}}
getRowId={(row) => row.id}
disabledSelectionKeys={[2]}
/>
);
},
@@ -251,7 +267,9 @@ export const EmptyData: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={[]}
selectionMode="multiple"
selection={{
selectionMode: "multiple",
}}
/>
);
},
@@ -338,10 +356,17 @@ export const LoadingWhileKeepingDataNoPlaceholders: Story = {
columnDefinitions={userColumnDef}
data={userData}
isLoading={isLoading}
loadingLabel="Laster innhold for tabell"
/>
</VStack>
);
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
expect(canvas.getAllByText("Laster innhold for tabell")).toHaveLength(1);
expect(canvas.getByText("foo2")).toBeInTheDocument();
},
};
const selectionPaginationSpy = fn();
@@ -360,10 +385,12 @@ export const SelectionPagination: Story = {
<DataTableAuto
columnDefinitions={userColumnDef}
data={dataToShow}
selectionMode="multiple"
onSelectionChange={(keys) => {
console.info({ keys });
selectionPaginationSpy(keys);
selection={{
selectionMode: "multiple",
onSelectionChange: (keys) => {
console.info({ keys });
selectionPaginationSpy(keys);
},
}}
getRowId={(row) => row.foo + row.bar}
/>
@@ -452,8 +479,10 @@ export const StickySelection: Story = {
defaultWidth: "350px",
}))}
data={userData}
selectionMode="multiple"
onSelectionChange={console.info}
selection={{
selectionMode: "multiple",
onSelectionChange: console.info,
}}
getRowId={(row) => row.foo + row.bar}
withKeyboardNav
stickyColumns={{
@@ -603,7 +632,7 @@ const sortableColumnDef: ColumnDefinitions<SortableUserDataTest> = [
id: "id",
header: "Id",
cell: ({ id }) => id,
type: "number",
align: "right",
sortable: true,
label: "Id",
},
@@ -686,7 +715,7 @@ export const SortableColumnsUncontrolled: Story = {
const rowClickSpy = fn();
const rowClickColumnDef: ColumnDefinitions<UserDataTest> = [
{ id: "id", header: "Id", cell: ({ id }) => id, type: "number", label: "Id" },
{ id: "id", header: "Id", cell: ({ id }) => id, align: "right", label: "Id" },
{ id: "foo", header: "Foo", cell: ({ foo }) => foo, label: "Foo" },
{
id: "link",
@@ -719,7 +748,9 @@ export const RowClick: Story = {
data={userData}
getRowId={(row) => row.id}
onRowClick={() => console.info("Row clicked!")}
selectionMode="multiple"
selection={{
selectionMode: "multiple",
}}
withKeyboardNav
/>
),
@@ -732,7 +763,9 @@ export const RowClickTest: Story = {
data={userData}
getRowId={(row) => row.id}
onRowClick={rowClickSpy}
selectionMode="multiple"
selection={{
selectionMode: "multiple",
}}
/>
),
play: async ({ canvasElement }) => {
@@ -769,7 +802,9 @@ export const RowExpansion: Story = {
data={userData}
getRowId={(row) => row.id}
onRowClick={() => console.info("Row clicked!")}
selectionMode={args.selectionMode}
selection={{
selectionMode: args.selectionMode,
}}
withKeyboardNav
getDetailsPanelContent={(rowData) => {
return <div>{`Details for ${rowData.foo} (id: ${rowData.id})`}</div>;
@@ -786,7 +821,9 @@ export const RowExpansionAll: Story = {
data={userData}
getRowId={(row) => row.id}
onRowClick={() => console.info("Row clicked!")}
selectionMode={args.selectionMode}
selection={{
selectionMode: args.selectionMode,
}}
withKeyboardNav
getDetailsPanelContent={(rowData) => {
return <div>{`Details for ${rowData.foo} (id: ${rowData.id})`}</div>;
@@ -814,10 +851,12 @@ export const NestedRows: Story = {
columnDefinitions={rowClickColumnDef}
data={nestedRowData}
getRowId={(row) => row.id}
selectionMode={args.selectionMode}
selection={{
selectionMode: args.selectionMode,
onSelectionChange: console.info,
}}
withKeyboardNav
getSubRows={(row) => row.children}
onSelectionChange={console.info}
/>
),
play: async ({ canvasElement }) => {
@@ -866,7 +905,9 @@ export const NestedLeftAlignedContentRows: Story = {
columnDefinitions={rowClickColumnDef.slice(1)}
data={nestedRowData}
getRowId={(row) => row.id}
selectionMode={args.selectionMode}
selection={{
selectionMode: args.selectionMode,
}}
withKeyboardNav
getSubRows={(row) => row.children}
/>
@@ -887,7 +928,9 @@ export const NestedOneLevelLeftAlignedContentRows: Story = {
})),
}))}
getRowId={(row) => row.id}
selectionMode={args.selectionMode}
selection={{
selectionMode: args.selectionMode,
}}
withKeyboardNav
getSubRows={(row) => row.children}
/>
@@ -908,7 +951,9 @@ export const NestedRowsWithMasterDetail: Story = {
})),
}))}
getRowId={(row) => row.id}
selectionMode={args.selectionMode}
selection={{
selectionMode: args.selectionMode,
}}
withKeyboardNav
getSubRows={(row) => row.children}
getDetailsPanelContent={() => <div>Placeholder content</div>}
@@ -62,6 +62,7 @@ const DataTableColumnHeader = forwardRef<
sortable = false,
sortDirection = "none",
onSortClick,
resizable = true,
style,
width,
defaultWidth,
@@ -81,6 +82,7 @@ const DataTableColumnHeader = forwardRef<
const mergedRef = useMergeRefs(forwardedRef, thRef);
const resizeResult = useTableColumnResize({
resizable,
thRef,
width,
defaultWidth,
@@ -11,6 +11,13 @@ import { useDataTableContext } from "../root/DataTableRoot.context";
type ColumnWidth = number | string;
type ResizeProps = {
/**
* Whether the column should be resizable by the user.
*
* **NB:** This is always disabled when `layout="auto"` on the root component.
* @default true
*/
resizable?: boolean;
/**
* Controlled width of the column.
*
@@ -18,7 +25,7 @@ type ResizeProps = {
*/
width?: ColumnWidth;
/**
* Initial width of the column. Only used when `width` is not set.
* Initial width of the column. Only used when `width` is not set and `resizable` is true.
*/
defaultWidth?: ColumnWidth;
/**
@@ -96,6 +103,7 @@ function useTableColumnResize(
args: TableColumnResizeArgs,
): TableColumnResizeResult {
const {
resizable,
thRef,
width: userWidth,
defaultWidth,
@@ -112,7 +120,7 @@ function useTableColumnResize(
const [isResizingWithKeyboard, setIsResizingWithKeyboard] = useState(false);
const ignoreNextOnClick = useRef(false);
const [width, _setWidth] = useControllableState({
const [width, setWidth] = useControllableState({
value: userWidth,
defaultValue: defaultWidth ?? (colSpan ?? 1) * 140,
/**
@@ -123,14 +131,14 @@ function useTableColumnResize(
onChange: onWidthChange,
});
const setWidth = useCallback(
const setClampedWidth = useCallback(
(newWidth: number) => {
const min = parseWidth(minWidth) ?? 0;
const max = parseWidth(maxWidth) ?? Infinity;
const clamped = Math.min(Math.max(newWidth, min), max);
_setWidth(clamped);
setWidth(clamped);
},
[minWidth, maxWidth, _setWidth],
[minWidth, maxWidth, setWidth],
);
// biome-ignore lint/correctness/useExhaustiveDependencies: We only want to run this on mount and when autoWidth changes
@@ -142,7 +150,7 @@ function useTableColumnResize(
const newColumnWidth = getAutoColumnWidth(thRef);
if (newColumnWidth) {
setWidth(newColumnWidth);
setClampedWidth(newColumnWidth);
}
},
[autoWidth], // eslint-disable-line react-hooks/exhaustive-deps
@@ -173,19 +181,19 @@ function useTableColumnResize(
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
event.preventDefault();
const delta = event.key === "ArrowRight" ? 20 : -20;
setWidth(currentWidth + delta);
setClampedWidth(currentWidth + delta);
return;
}
if (event.key === "Home") {
event.preventDefault();
setWidth(0); // will fall back to minWidth
setClampedWidth(0); // will fall back to minWidth
return;
}
if (event.key === "End") {
event.preventDefault();
const newWidth = getAutoColumnWidth(thRef);
if (newWidth && newWidth > currentWidth) {
setWidth(newWidth);
setClampedWidth(newWidth);
}
return;
}
@@ -193,7 +201,7 @@ function useTableColumnResize(
setIsResizingWithKeyboard(false);
}
},
[isResizingWithKeyboard, setWidth, thRef],
[isResizingWithKeyboard, setClampedWidth, thRef],
);
const startResize = useCallback(
@@ -216,7 +224,7 @@ function useTableColumnResize(
return;
}
setWidth(newWidth);
setClampedWidth(newWidth);
}
function onMouseMove(e: MouseEvent) {
@@ -244,7 +252,7 @@ function useTableColumnResize(
document.addEventListener("touchend", cleanup, { once: true });
document.addEventListener("touchcancel", cleanup, { once: true });
},
[maxWidth, minWidth, setWidth, thRef],
[maxWidth, minWidth, setWidth, setClampedWidth, thRef],
);
const handleMouseDown: DOMAttributes<HTMLButtonElement>["onMouseDown"] =
@@ -268,9 +276,9 @@ function useTableColumnResize(
useCallback(() => {
const newColumnWidth = getAutoColumnWidth(thRef);
if (newColumnWidth) {
setWidth(newColumnWidth);
setClampedWidth(newColumnWidth);
}
}, [setWidth, thRef]);
}, [setClampedWidth, thRef]);
if (tableContext.layout !== "fixed") {
return {
@@ -279,6 +287,16 @@ function useTableColumnResize(
};
}
if (!resizable) {
return {
style: {
...style,
width,
},
enabled: false,
};
}
return {
style: {
...style,
@@ -16,8 +16,7 @@ type NavigationAction =
/**
* Maps keyboard events to navigation actions.
* Supports arrow keys, Home/End (row navigation), Ctrl/Cmd+Home/End (table navigation),
* and PageUp/PageDown (multi-row navigation).
* Supports arrow keys, Home/End (row navigation), Ctrl/Cmd+Home/End (table navigation).
*/
function getNavigationAction(event: KeyboardEvent): NavigationAction | null {
const key = event.key;
@@ -1,115 +0,0 @@
import { act, renderHook } from "@testing-library/react";
import React from "react";
import { describe, expect, test, vi } from "vitest";
import {
DataTableExpansionProvider,
useDataTableExpansion,
} from "../useTableExpansion";
import { useTableItems } from "../useTableItems";
type TestRow = {
id: number;
subRows?: TestRow[];
};
function createWrapper(
options: {
onDetailsPanelChange?: (ids: (string | number)[]) => void;
isDetailsPanelExpandable?: (row: TestRow) => boolean;
} = {},
) {
const rows: TestRow[] = [{ id: 1, subRows: [{ id: 10 }] }, { id: 2 }];
return function Wrapper({ children }: { children: React.ReactNode }) {
const tableItems = useTableItems({
items: rows,
getRowId: (row) => row.id,
getSubRows: (row) => row.subRows ?? [],
});
return (
<DataTableExpansionProvider<TestRow>
itemDetails={tableItems.itemDetails}
getDetailsPanelContent={(row) => row.id}
isDetailsPanelExpandable={options.isDetailsPanelExpandable}
onDetailsPanelChange={options.onDetailsPanelChange}
>
{children}
</DataTableExpansionProvider>
);
};
}
describe("useTableExpansion", () => {
test("does not allow toggling rows that are not expandable", () => {
const onDetailsPanelChange = vi.fn();
const { result } = renderHook(() => useDataTableExpansion(), {
wrapper: createWrapper({
onDetailsPanelChange,
isDetailsPanelExpandable: (row) => row.id === 1,
}),
});
expect(result.current.isDetailsPanelExpandable(1)).toBe(true);
expect(result.current.isDetailsPanelExpandable(2)).toBe(false);
expect(result.current.isDetailsPanelExpandable(10)).toBe(false);
act(() => {
result.current.toggleExpansion(2);
});
expect(result.current.isExpanded(2)).toBe(false);
expect(onDetailsPanelChange).not.toHaveBeenCalled();
act(() => {
result.current.toggleExpansion(1);
});
expect(result.current.isExpanded(1)).toBe(true);
expect(onDetailsPanelChange).toHaveBeenCalledWith([1]);
});
test("expand all only expands expandable rows", () => {
const onDetailsPanelChange = vi.fn();
const { result } = renderHook(() => useDataTableExpansion(), {
wrapper: createWrapper({
onDetailsPanelChange,
isDetailsPanelExpandable: (row) => row.id === 1,
}),
});
act(() => {
result.current.toggleAll();
});
expect(result.current.isExpanded(1)).toBe(true);
expect(result.current.isExpanded(2)).toBe(false);
expect(result.current.isAllExpanded).toBe(true);
expect(onDetailsPanelChange).toHaveBeenCalledWith([1]);
});
test("expand all only targets top-level table items", () => {
const onDetailsPanelChange = vi.fn();
const { result } = renderHook(() => useDataTableExpansion(), {
wrapper: createWrapper({
onDetailsPanelChange,
}),
});
expect(result.current.isDetailsPanelExpandable(1)).toBe(true);
expect(result.current.isDetailsPanelExpandable(2)).toBe(true);
expect(result.current.isDetailsPanelExpandable(10)).toBe(false);
act(() => {
result.current.toggleAll();
});
expect(result.current.isExpanded(1)).toBe(true);
expect(result.current.isExpanded(2)).toBe(true);
expect(result.current.isExpanded(10)).toBe(false);
expect(onDetailsPanelChange).toHaveBeenCalledWith([1, 2]);
});
});
@@ -12,11 +12,12 @@ type ColumnDefinition<T> = {
minWidth?: number | string;
maxWidth?: number | string;
/**
* Currently only handles cell alignment.
* TODO: Should this include centering?
* type "icon" or something to avoid ellipsis on actions, tags etc
* Text alignment for cells in this column.
*
*
* @default "left"
*/
type?: "string" | "number";
align?: "left" | "right" | "center";
/**
* Assigned to the cell's `th` element instead of `td` if true.
*
@@ -63,7 +63,7 @@ describe("DataTableAuto", () => {
data={data}
getRowId={(row) => row.id}
getSubRows={(row) => row.subRows ?? []}
selectionMode="multiple"
selection={{ selectionMode: "multiple" }}
/>,
);
@@ -92,7 +92,7 @@ describe("DataTableAuto", () => {
data={fallbackIdData}
getSubRows={(row) => row.subRows ?? []}
defaultExpandedSubRowIds={[0]}
selectionMode="multiple"
selection={{ selectionMode: "multiple" }}
/>,
);
@@ -115,7 +115,7 @@ describe("DataTableAuto", () => {
data={data}
getRowId={(row) => row.id}
getSubRows={(row) => row.subRows ?? []}
selectionMode="multiple"
selection={{ selectionMode: "multiple" }}
/>,
);
@@ -147,7 +147,7 @@ describe("DataTableAuto", () => {
data={deepNestedData}
getRowId={(row) => row.id}
getSubRows={(row) => row.subRows ?? []}
selectionMode="multiple"
selection={{ selectionMode: "multiple" }}
/>,
);
@@ -184,7 +184,7 @@ describe("DataTableAuto", () => {
data={deepNestedData}
getRowId={(row) => row.id}
getSubRows={(row) => row.subRows ?? []}
selectionMode="multiple"
selection={{ selectionMode: "multiple" }}
/>,
);
@@ -38,10 +38,7 @@ import {
} from "./DataTableRoot.context";
interface DataTableProps<T>
extends
React.HTMLAttributes<HTMLTableElement>,
SelectionProps,
TableSortOptions {
extends React.HTMLAttributes<HTMLTableElement>, TableSortOptions {
children?: never;
/**
* Controls vertical cell padding.
@@ -202,12 +199,20 @@ interface DataTableProps<T>
/**
* Function to get sub-rows for a given row, used for nested rows.
* When provided, an expand toggle column is added automatically.
*
*
* TODO:
* - Table might need to be implemented with role="treegrid" for a11y when having nested rows.
*/
getSubRows?: (rowData: T) => T[];
expandedSubRowIds?: (string | number)[];
defaultExpandedSubRowIds?: (string | number)[];
isSubRowExpandable?: (rowData: T) => boolean;
onExpandedSubRowIdsChange?: (ids: (string | number)[]) => void;
/**
* Props for row selection functionality.
*/
selection?: SelectionProps;
}
function DataTableAutoInner<T>(
@@ -220,11 +225,7 @@ function DataTableAutoInner<T>(
truncateContent = true,
shouldBlockNavigation,
layout = "fixed",
selectionMode: selectionModeProp = "none",
selectedKeys,
defaultSelectedKeys,
onSelectionChange,
disabledSelectionKeys = [],
selection,
data,
columnDefinitions,
getRowId,
@@ -239,7 +240,6 @@ function DataTableAutoInner<T>(
loadingState,
loadingRows,
loadingLabel = "Laster innhold",
disableRowSelectionOnClick = false,
getDetailsPanelContent,
isDetailsPanelExpandable,
getDetailsPanelHeight,
@@ -279,6 +279,15 @@ function DataTableAutoInner<T>(
onExpandedSubRowIdsChange,
});
const {
selectionMode: selectionModeProp = "none",
selectedKeys,
defaultSelectedKeys,
onSelectionChange,
disabledSelectionKeys = [],
disableRowSelectionOnClick = false,
} = selection || {};
const tableSelectionState = useTableSelection({
selectionMode: selectionModeProp,
selectedKeys,
@@ -359,9 +368,7 @@ function DataTableAutoInner<T>(
minWidth={colDef.minWidth}
width={colDef.width}
defaultWidth={colDef.defaultWidth ?? "100%"}
textAlign={
colDef.type === "number" ? "right" : "left"
}
textAlign={colDef.align ?? "left"}
key={colDef.id}
isSticky={isSticky}
sortable={colDef.sortable}
@@ -431,7 +438,7 @@ function DataTableAutoTBodyContent({
<DataTableTr key={`skeleton-row-${rowIndex}`} aria-hidden>
{columns.map(({ isSticky, colDef }, colDefIndex) => (
<DataTableBaseCell
textAlign={colDef.type === "number" ? "right" : "left"}
textAlign={colDef.align ?? "left"}
key={colDef.id || colDefIndex}
as={colDef.isRowHeader ? "th" : "td"}
isSticky={isSticky}
@@ -455,59 +462,64 @@ function DataTableAutoTBodyContent({
const renderLoadingAnnouncement = isLoading && !loadingState && !loadingRows;
return items.map((rowData) => {
const details = itemDetails.get(rowData);
return (
<>
{renderLoadingAnnouncement && (
<tr>
<td colSpan={fullWidthColSpan} className="aksel-sr-only">
{loadingLabel}
</td>
</tr>
)}
{items.map((rowData) => {
const details = itemDetails.get(rowData);
/* Should in theory be impossible. Look about typing this? */
if (!details) {
return null;
}
/* Should in theory be impossible. Look about typing this? */
if (!details) {
return null;
}
const hasSubRows = details.children.length > 0;
const hasSubRows = details.children.length > 0;
return (
<React.Fragment key={details.id}>
{renderLoadingAnnouncement && (
<tr>
<td colSpan={fullWidthColSpan} className="aksel-sr-only">
{loadingLabel}
</td>
</tr>
)}
<DataTableTr rowId={details.id}>
{columns.map(({ isSticky, colDef }, colDefIndex) => {
const renderNestedToggle = colDefIndex === 0 && hasSubRows;
const renderNestedIndent =
colDefIndex === 0 && (details.level > 0 || hasSubRows);
return (
<React.Fragment key={details.id}>
<DataTableTr rowId={details.id}>
{columns.map(({ isSticky, colDef }, colDefIndex) => {
const renderNestedToggle = colDefIndex === 0 && hasSubRows;
const renderNestedIndent =
colDefIndex === 0 && (details.level > 0 || hasSubRows);
const style: React.CSSProperties = {
"--__axc-data-table-nested-depth": details.level,
};
const style: React.CSSProperties = {
"--__axc-data-table-nested-depth": details.level,
};
return (
<DataTableBaseCell
/* TODO: Make this configurable */
textAlign={colDef.type === "number" ? "right" : "left"}
key={colDef.id || colDefIndex}
as={colDef.isRowHeader ? "th" : "td"}
isSticky={isSticky}
data-nested={renderNestedIndent || undefined}
style={style}
>
{renderNestedToggle && <NestedRowToggle details={details} />}
{colDef.cell(rowData)}
</DataTableBaseCell>
);
})}
</DataTableTr>
<DataTableExpandedRow
rowId={details.id}
rowData={rowData}
fullWidthColSpan={fullWidthColSpan}
/>
</React.Fragment>
);
});
return (
<DataTableBaseCell
textAlign={colDef.align ?? "left"}
key={colDef.id || colDefIndex}
as={colDef.isRowHeader ? "th" : "td"}
isSticky={isSticky}
data-nested={renderNestedIndent || undefined}
style={style}
>
{renderNestedToggle && (
<NestedRowToggle details={details} />
)}
{colDef.cell(rowData)}
</DataTableBaseCell>
);
})}
</DataTableTr>
<DataTableExpandedRow
rowId={details.id}
rowData={rowData}
fullWidthColSpan={fullWidthColSpan}
/>
</React.Fragment>
);
})}
</>
);
}
function NestedRowToggle({ details }: { details: ItemDetail<any> }) {
@@ -576,12 +588,16 @@ function DataTableExpandedRow<T>({
return null;
}
const panelHeight = getDetailsPanelHeight?.(rowData);
const style: React.CSSProperties = panelHeight
? { height: panelHeight, overflow: "auto" }
: { height: "auto" };
return (
<tr>
<td id={expansionId} colSpan={fullWidthColSpan}>
<div style={{ height: getDetailsPanelHeight?.(rowData) }}>
{content}
</div>
<div style={style}>{content}</div>
</td>
</tr>
);
@@ -231,7 +231,7 @@ const DataTable = forwardRef<HTMLTableElement, DataTableProps>(
withKeyboardNav={withKeyboardNav}
selectionState={noSelectionState}
stickySelection={false}
stickyHeader={false}
stickyHeader={true}
tableId={useId()}
showLoadingSkeletons={false}
onRowClick={undefined}
@@ -35,6 +35,7 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
"indeterminate",
"errorId",
"readOnly",
"className",
])}
{...omit(inputProps, ["aria-invalid", "aria-describedby"])}
aria-describedby={
+7 -1
View File
@@ -24,7 +24,13 @@ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
>
<RadioInput
ref={forwardedRef}
{...omit(props, ["children", "size", "description", "readOnly"])}
{...omit(props, [
"children",
"size",
"description",
"readOnly",
"className",
])}
{...omit(inputProps, ["aria-invalid", "aria-describedby"])}
aria-describedby={
cl(inputProps["aria-describedby"], {
+8 -4
View File
@@ -39,7 +39,8 @@ interface ModalPropsBase extends React.DialogHTMLAttributes<HTMLDialogElement> {
/**
* Called when the user tries to close the modal by one of the built-in methods.
* Used if you want to ask the user for confirmation before closing.
* @warning Will not always be called when pressing Esc. See `onCancel` for more info.
*
* **NB:** Will not always be called when pressing Esc. See `onCancel` for more info.
* @returns Whether to close the modal or not
*/
onBeforeClose?: () => boolean;
@@ -52,7 +53,8 @@ interface ModalPropsBase extends React.DialogHTMLAttributes<HTMLDialogElement> {
onCancel?: React.ReactEventHandler<HTMLDialogElement>;
/**
* Whether to close when clicking on the backdrop.
* @warning Users may click outside by accident. Don't use if closing can cause data loss, or the modal contains important info.
*
* **NB:** Users may click outside by accident. Don't use if closing can cause data loss, or the modal contains important info.
* @default false
*/
closeOnBackdropClick?: boolean;
@@ -77,13 +79,15 @@ interface ModalPropsBase extends React.DialogHTMLAttributes<HTMLDialogElement> {
/**
* ID of the element that labels the modal.
* No need to set this manually if the `header` prop is used. A reference to `header.heading` will be created automatically.
* @warning If not using `header`, you should set either `aria-labelledby` or `aria-label`.
*
* **NB:** If not using `header`, you should set either `aria-labelledby` or `aria-label`.
*/
"aria-labelledby"?: string;
/**
* String value that labels the modal.
* No need to set this if the `header` prop is used.
* @warning If not using `header`, you should set either `aria-labelledby` or `aria-label`.
*
* **NB:** If not using `header`, you should set either `aria-labelledby` or `aria-label`.
*/
"aria-label"?: string;
}
@@ -7,218 +7,139 @@ interface TranslationMap {
export default {
global: {
dateLocale: nb,
/** @default "Vis mer" */
showMore: "Vis mer",
/** @default "Vis mindre" */
showLess: "Vis mindre",
/** @default "Skrivebeskyttet" */
readOnly: "Skrivebeskyttet",
/** @default "Lukk" */
close: "Lukk",
/** @default "Feil" */
error: "Feil",
/** @default "Informasjon" */
info: "Informasjon",
/** @default "Suksess" */
success: "Suksess",
/** @default "Advarsel" */
warning: "Advarsel",
/** @default "Kunngjøring" */
announcement: "Kunngjøring",
},
Chips: {
Removable: {
/** Will be appended to the accessible name for the button.
* @default "slett" */
/** Will be appended to the accessible name for the button. */
labelSuffix: "slett",
},
},
Combobox: {
/** The input value will be appended to the end of this text, e.g. `Legg til "input value"`.
* @default "Legg til" */
/** The input value will be appended to the end of this text, e.g. `Legg til "input value"`. */
addOption: "Legg til",
/** @default "Ingen søketreff" */
noMatches: "Ingen søketreff",
/** Loader title
* @default "Søker…" */
/** Loader title */
loading: "Søker…",
/** @default "{selected} av maks {limit} er valgt." */
maxSelected: "{selected} av maks {limit} er valgt.",
},
CopyButton: {
/** @default "Kopier" */
title: "Kopier",
/** @default "Kopiert!" */
activeText: "Kopiert!",
},
DatePicker: {
/** @default "Velg dato" */
chooseDate: "Velg dato",
/** @default "Velg datoer" */
chooseDates: "Velg datoer",
/** @default "Velg start- og sluttdato" */
chooseDateRange: "Velg start- og sluttdato",
/** @default "Velg måned" */
chooseMonth: "Velg måned",
/** @default "Uke" */
week: "Uke",
/** @default "Uke {week}" */
weekNumber: "Uke {week}",
/** @default "Velg uke {week}" */
selectWeekNumber: "Velg uke {week}",
/** @default "Måned" */
month: "Måned",
/** @default "Gå til neste måned" */
goToNextMonth: "Gå til neste måned",
/** @default "Gå til forrige måned" */
goToPreviousMonth: "Gå til forrige måned",
/** @default "År" */
year: "År",
/** @default "Gå til neste år" */
goToNextYear: "Gå til neste år",
/** @default "Gå til forrige år" */
goToPreviousYear: "Gå til forrige år",
/** @default "Åpne datovelger" */
openDatePicker: "Åpne datovelger",
/** @default "Åpne månedsvelger" */
openMonthPicker: "Åpne månedsvelger",
/** @default "Lukk datovelger" */
closeDatePicker: "Lukk datovelger",
/** @default "Lukk månedsvelger" */
closeMonthPicker: "Lukk månedsvelger",
},
ErrorSummary: {
/** @default "Du må rette disse feilene før du kan fortsette:" */
heading: "Du må rette disse feilene før du kan fortsette:",
},
FileUpload: {
dropzone: {
/** @default "Velg fil" */
button: "Velg fil",
/** @default "Velg filer" */
buttonMultiple: "Velg filer",
/** @default "Dra og slipp filen her" */
dragAndDrop: "Dra og slipp filen her",
/** @default "Dra og slipp filer her" */
dragAndDropMultiple: "Dra og slipp filer her",
/** @default "Slipp" */
drop: "Slipp",
/** @default "eller" */
or: "eller",
/** @default "Filopplasting er deaktivert" */
disabled: "Filopplasting er deaktivert",
/** @default "Du kan ikke laste opp flere filer" */
disabledFilelimit: "Du kan ikke laste opp flere filer",
},
item: {
/** @default "Prøv å laste opp filen på nytt" */
retryButtonTitle: "Prøv å laste opp filen på nytt",
/** @default "Slett filen" */
deleteButtonTitle: "Slett filen",
/** @default "Laster opp…" */
uploading: "Laster opp…",
/** @default "Laster ned…" */
downloading: "Laster ned…",
},
},
FormProgress: {
/** @default "Steg {activeStep} av {totalSteps}" */
step: "Steg {activeStep} av {totalSteps}",
/** @default "Vis alle steg" */
showAllSteps: "Vis alle steg",
/** @default "Skjul alle steg" */
hideAllSteps: "Skjul alle steg",
},
FormSummary: {
/** @default "Endre svar" */
editAnswer: "Endre svar",
},
GuidePanel: {
/** @default "Illustrasjon av veileder" */
illustrationLabel: "Illustrasjon av veileder",
},
HelpText: {
/** @default "Mer informasjon" */
title: "Mer informasjon",
},
Loader: {
/** @default "Venter…" */
title: "Venter…",
},
Pagination: {
/** @default "Forrige" */
previous: "Forrige",
/** @default "Neste" */
next: "Neste",
},
Process: {
/** @default "Aktiv" */
active: "Aktiv",
},
ProgressBar: {
/** @default "{current} av {max}" */
progress: "{current} av {max}",
/** @default "Fremdrift kan ikke beregnes, antatt tid er {seconds} sekunder." */
progressUnknown:
"Fremdrift kan ikke beregnes, antatt tid er {seconds} sekunder.",
},
Search: {
/** @default "Tøm feltet" */
clear: "Tøm feltet",
/** @default "Søk" */
search: "Søk",
},
Textarea: {
/** Screen readers only
* @default "Tekstområde med plass til {maxLength} tegn." */
/** Screen readers only */
maxLength: "Tekstområde med plass til {maxLength} tegn.",
/** @default "{chars} tegn for mye" */
charsTooMany: "{chars} tegn for mye",
/** @default "{chars} tegn igjen" */
charsLeft: "{chars} tegn igjen",
},
Timeline: {
/** @default "dd.MM.yyyy" */
dateFormat: "dd.MM.yyyy",
/** @default "dd.MM" */
dayFormat: "dd.MM",
/** @default "MMM yy" */
monthFormat: "MMM yy",
/** @default "yyyy" */
yearFormat: "yyyy",
Row: {
/** @default "Ingen perioder" */
noPeriods: "Ingen perioder",
/** @default "{start} til {end}" */
period: "{start} til {end}",
},
Period: {
/** @default "Suksess" */
success: "Suksess",
/** @default "Advarsel" */
warning: "Advarsel",
/** @default "Fare" */
danger: "Fare",
/** @default "Info" */
info: "Info",
/** @default "Nøytral" */
neutral: "Nøytral",
/** @default "{status} fra {start} til {end}" */
period: "{status} fra {start} til {end}",
},
Pin: {
/** @default "Pin: {date}" */
pin: "Pin: {date}",
},
Zoom: {
/** @default "Zoom tidslinjen {start} til {end}" */
zoom: "Zoom tidslinjen {start} til {end}",
/** @default "Tilbakestill tidsperspektiv" */
reset: "Tilbakestill tidsperspektiv",
},
},
Tooltip: {
/** @default "eller" */
shortcutSeparator: "eller",
},
} satisfies TranslationMap;
+2
View File
@@ -1,5 +1,7 @@
# @navikt/ds-tailwind
## 8.10.3
## 8.10.2
## 8.10.1
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tailwind",
"version": "8.10.2",
"version": "8.10.3",
"description": "Tailwind config based on @navikt/ds-tokens",
"author": "Aksel | Nav designsystem team",
"keywords": [
@@ -27,7 +27,7 @@
},
"homepage": "https://aksel.nav.no/grunnleggende/kode/tailwind/",
"devDependencies": {
"@navikt/ds-tokens": "^8.10.2",
"@navikt/ds-tokens": "^8.10.3",
"tailwindcss": "^3.3.3",
"tsx": "^4.20.6",
"typescript": "6.0.2",
+2
View File
@@ -1,5 +1,7 @@
# @navikt/ds-tokens
## 8.10.3
## 8.10.2
## 8.10.1
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@navikt/ds-tokens",
"version": "8.10.2",
"version": "8.10.3",
"description": "Design-tokens for Nav designsystem",
"author": "Aksel | Nav designsystem team",
"keywords": [
+10
View File
@@ -1,5 +1,15 @@
# Changelog
## 8.10.3
### @navikt/ds-react
- Radio, Checkbox: Fix regression where `className` was mistakenly passed to `input`-element ([#4837](https://github.com/navikt/aksel/pull/4837))
### @navikt/ds-css
- Add module declaration to avoid TypeScript error when importing ([`92f6d9e`](https://github.com/navikt/aksel/commit/92f6d9e93b879962df8415f7fad22203174dd3a8))
## 8.10.2
### @navikt/ds-css
+6 -6
View File
@@ -15,11 +15,11 @@
"playroom"
],
"dependencies": {
"@navikt/aksel": "^8.10.2",
"@navikt/aksel-icons": "^8.10.2",
"@navikt/ds-css": "^8.10.2",
"@navikt/ds-react": "^8.10.2",
"@navikt/ds-tailwind": "^8.10.2",
"@navikt/ds-tokens": "^8.10.2"
"@navikt/aksel": "^8.10.3",
"@navikt/aksel-icons": "^8.10.3",
"@navikt/ds-css": "^8.10.3",
"@navikt/ds-react": "^8.10.3",
"@navikt/ds-tailwind": "^8.10.3",
"@navikt/ds-tokens": "^8.10.3"
}
}
@@ -7,9 +7,11 @@ import styles from "./PropsSeksjon.module.css";
function PropsSeksjonDescription({
description,
params,
returnVal,
}: {
description?: string;
params?: string[];
description: string | undefined;
params: string[] | undefined;
returnVal: string | undefined;
}) {
if (!description) {
return null;
@@ -30,20 +32,26 @@ function PropsSeksjonDescription({
>
{description}
</Markdown>
{params && (
<ul>
{params.map((param) => {
const [name, ...desc] = param.split(" ");
return (
<li key={param}>
<strong>{name}: </strong>
{desc.join(" ")}
</li>
);
})}
</ul>
)}
{returnVal && (
<div>
<strong>Return: </strong>
{returnVal}
</div>
)}
</VStack>
{params && (
<ul>
{params.map((param) => {
const [name, ...desc] = param.split(" ");
return (
<li key={param}>
<strong>{name}: </strong>
{desc.join(" ")}
</li>
);
})}
</ul>
)}
</div>
</li>
);
@@ -86,55 +86,22 @@ const PropEntry = ({
NonNullable<PropsSeksjonComponentT["propref"]>["proplist"]
>[0];
}) => {
if (prop.deprecated) {
return (
<>
<Box
as="dt"
paddingBlock="space-8 space-0"
paddingInline="space-8"
className="inline-block"
>
<Code as="h4" className="mr-2" strikethrough highlighted>{`${
prop.name
}${prop?.required ? "" : "?"}`}</Code>
</Box>
<BodyShort as="dd">
<Box as="ul" overflowX="auto">
<PropsSeksjonDeprecation text={prop.deprecated} />
<PropsSeksjonCode code={prop.type} title="Type" wrap />
<PropsSeksjonCode
/* We assume that if type starts with ", its an union-type */
code={prop.defaultValue}
title="Default"
wrap
/>
<PropsSeksjonDescription
description={prop.description}
params={prop.params}
/>
<PropsSeksjonCode code={prop.example} title="Example" />
</Box>
</BodyShort>
</>
);
}
let type = prop.type;
if (prop.type === "AkselColor") {
type = unpackAkselColorType();
}
const type = prop.type === "AkselColor" ? unpackedAkselColorType : prop.type;
return (
<>
<Box as="dt" paddingBlock="space-8 space-0" paddingInline="space-8">
<Code as="h4" highlighted>{`${prop.name}${
prop?.required ? "" : "?"
}`}</Code>
<Code
as="h4"
highlighted
strikethrough={!!prop.deprecated}
>{`${prop.name}${prop?.required ? "" : "?"}`}</Code>
</Box>
<BodyShort as="dd">
<Box as="ul" overflowX="auto">
{prop.deprecated && (
<PropsSeksjonDeprecation text={prop.deprecated} />
)}
<PropsSeksjonCode code={type} title="Type" wrap />
<PropsSeksjonCode
/* We assume that if type starts with ", its an union-type */
@@ -145,6 +112,7 @@ const PropEntry = ({
<PropsSeksjonDescription
description={prop.description}
params={prop.params}
returnVal={prop.return}
/>
<PropsSeksjonCode code={prop.example} title="Example" />
</Box>
@@ -167,10 +135,8 @@ const colors: Record<AkselColorRole, boolean> = {
"brand-magenta": true,
};
function unpackAkselColorType() {
return Object.keys(colors)
.map((key) => `"${key}"`)
.join(" | ");
}
const unpackedAkselColorType = Object.keys(colors)
.map((key) => `"${key}"`)
.join(" | ");
export { PropsSeksjon };
+4 -2
View File
@@ -10,9 +10,11 @@ function analyzeCss(tarLocation: string): number {
const cssPackageDir = unpackTar(tarLocation);
const cssPackageExports = getPackageExports(cssPackageDir);
const exportPath = cssPackageExports["."];
const exportEntry = cssPackageExports["."];
const exportPath =
typeof exportEntry === "string" ? exportEntry : exportEntry?.default;
/* We assume key-value to be string for css-package */
/* We assume max one level of nesting for css-package exports */
assert(
exportPath && typeof exportPath === "string",
"Package export '.' not found for css-package",
+20 -20
View File
@@ -5011,7 +5011,7 @@ __metadata:
languageName: node
linkType: hard
"@navikt/aksel-icons@npm:^8.10.2, @navikt/aksel-icons@workspace:@navikt/aksel-icons":
"@navikt/aksel-icons@npm:^8.10.3, @navikt/aksel-icons@workspace:@navikt/aksel-icons":
version: 0.0.0-use.local
resolution: "@navikt/aksel-icons@workspace:@navikt/aksel-icons"
dependencies:
@@ -5042,8 +5042,8 @@ __metadata:
version: 0.0.0-use.local
resolution: "@navikt/aksel-stylelint@workspace:@navikt/aksel-stylelint"
dependencies:
"@navikt/ds-css": "npm:^8.10.2"
"@navikt/ds-tokens": "npm:^8.10.2"
"@navikt/ds-css": "npm:^8.10.3"
"@navikt/ds-tokens": "npm:^8.10.3"
concurrently: "npm:9.2.1"
postcss-selector-parser: "npm:^7.1.0"
postcss-value-parser: "npm:^4.2.0"
@@ -5054,12 +5054,12 @@ __metadata:
languageName: unknown
linkType: soft
"@navikt/aksel@npm:^8.10.2, @navikt/aksel@workspace:@navikt/aksel":
"@navikt/aksel@npm:^8.10.3, @navikt/aksel@workspace:@navikt/aksel":
version: 0.0.0-use.local
resolution: "@navikt/aksel@workspace:@navikt/aksel"
dependencies:
"@navikt/ds-css": "npm:^8.10.2"
"@navikt/ds-tokens": "npm:^8.10.2"
"@navikt/ds-css": "npm:^8.10.3"
"@navikt/ds-tokens": "npm:^8.10.3"
"@types/cli-progress": "npm:3.11.6"
"@types/is-git-clean": "npm:1.1.2"
"@types/jscodeshift": "npm:17.3.0"
@@ -5089,11 +5089,11 @@ __metadata:
languageName: node
linkType: hard
"@navikt/ds-css@npm:*, @navikt/ds-css@npm:^8.10.2, @navikt/ds-css@workspace:@navikt/core/css":
"@navikt/ds-css@npm:*, @navikt/ds-css@npm:^8.10.3, @navikt/ds-css@workspace:@navikt/core/css":
version: 0.0.0-use.local
resolution: "@navikt/ds-css@workspace:@navikt/core/css"
dependencies:
"@navikt/ds-tokens": "npm:^8.10.2"
"@navikt/ds-tokens": "npm:^8.10.3"
browserslist: "npm:^4.25.0"
esbuild: "npm:^0.27.4"
fast-glob: "npm:3.3.3"
@@ -5103,14 +5103,14 @@ __metadata:
languageName: unknown
linkType: soft
"@navikt/ds-react@npm:*, @navikt/ds-react@npm:^8.10.2, @navikt/ds-react@workspace:@navikt/core/react":
"@navikt/ds-react@npm:*, @navikt/ds-react@npm:^8.10.3, @navikt/ds-react@workspace:@navikt/core/react":
version: 0.0.0-use.local
resolution: "@navikt/ds-react@workspace:@navikt/core/react"
dependencies:
"@floating-ui/react": "npm:0.27.8"
"@floating-ui/react-dom": "npm:^2.1.8"
"@navikt/aksel-icons": "npm:^8.10.2"
"@navikt/ds-tokens": "npm:^8.10.2"
"@navikt/aksel-icons": "npm:^8.10.3"
"@navikt/ds-tokens": "npm:^8.10.3"
"@testing-library/dom": "npm:10.4.1"
"@testing-library/jest-dom": "npm:^6.6.3"
"@testing-library/react": "npm:^16.3.0"
@@ -5146,11 +5146,11 @@ __metadata:
languageName: unknown
linkType: soft
"@navikt/ds-tailwind@npm:^8.10.2, @navikt/ds-tailwind@workspace:@navikt/core/tailwind":
"@navikt/ds-tailwind@npm:^8.10.3, @navikt/ds-tailwind@workspace:@navikt/core/tailwind":
version: 0.0.0-use.local
resolution: "@navikt/ds-tailwind@workspace:@navikt/core/tailwind"
dependencies:
"@navikt/ds-tokens": "npm:^8.10.2"
"@navikt/ds-tokens": "npm:^8.10.3"
tailwindcss: "npm:^3.3.3"
tsx: "npm:^4.20.6"
typescript: "npm:6.0.2"
@@ -5158,7 +5158,7 @@ __metadata:
languageName: unknown
linkType: soft
"@navikt/ds-tokens@npm:^8.10.2, @navikt/ds-tokens@workspace:@navikt/core/tokens":
"@navikt/ds-tokens@npm:^8.10.3, @navikt/ds-tokens@workspace:@navikt/core/tokens":
version: 0.0.0-use.local
resolution: "@navikt/ds-tokens@workspace:@navikt/core/tokens"
dependencies:
@@ -10075,12 +10075,12 @@ __metadata:
version: 0.0.0-use.local
resolution: "aksel.nav.no@workspace:aksel.nav.no"
dependencies:
"@navikt/aksel": "npm:^8.10.2"
"@navikt/aksel-icons": "npm:^8.10.2"
"@navikt/ds-css": "npm:^8.10.2"
"@navikt/ds-react": "npm:^8.10.2"
"@navikt/ds-tailwind": "npm:^8.10.2"
"@navikt/ds-tokens": "npm:^8.10.2"
"@navikt/aksel": "npm:^8.10.3"
"@navikt/aksel-icons": "npm:^8.10.3"
"@navikt/ds-css": "npm:^8.10.3"
"@navikt/ds-react": "npm:^8.10.3"
"@navikt/ds-tailwind": "npm:^8.10.3"
"@navikt/ds-tokens": "npm:^8.10.3"
languageName: unknown
linkType: soft