@dbcdk/react-components 0.0.120 → 0.0.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/card/Card.cjs +4 -7
- package/dist/components/card/Card.js +4 -7
- package/dist/components/card/Card.module.css +4 -9
- package/dist/components/search-box/SearchBox.cjs +9 -4
- package/dist/components/search-box/SearchBox.js +9 -4
- package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.cjs +1 -1
- package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.js +1 -1
- package/dist/components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem.module.css +11 -7
- package/dist/components/table/Table.cjs +9 -4
- package/dist/components/table/Table.d.ts +1 -1
- package/dist/components/table/Table.js +10 -5
- package/dist/components/table/Table.module.css +25 -0
- package/dist/components/table/Table.types.d.ts +13 -0
- package/dist/components/table/TanstackTable.cjs +10 -1
- package/dist/components/table/TanstackTable.js +10 -1
- package/dist/components/table/components/TableBody.cjs +2 -0
- package/dist/components/table/components/TableBody.d.ts +7 -2
- package/dist/components/table/components/TableBody.js +2 -0
- package/dist/components/table/components/TableHeader.cjs +10 -1
- package/dist/components/table/components/TableHeader.d.ts +2 -1
- package/dist/components/table/components/TableHeader.js +10 -1
- package/dist/components/table/components/TableRow.cjs +75 -1
- package/dist/components/table/components/TableRow.d.ts +7 -2
- package/dist/components/table/components/TableRow.js +75 -1
- package/dist/components/table/hooks/useTableRowInteractions.cjs +2 -2
- package/dist/components/table/hooks/useTableRowInteractions.js +2 -2
- package/dist/components/table/table.utils.cjs +2 -0
- package/dist/components/table/table.utils.d.ts +1 -0
- package/dist/components/table/table.utils.js +2 -1
- package/dist/components/table/tanstackTable.utils.cjs +6 -4
- package/dist/components/table/tanstackTable.utils.d.ts +2 -0
- package/dist/components/table/tanstackTable.utils.js +7 -5
- package/package.json +1 -1
- package/dist/components/table/components/TableLoadingBody.cjs +0 -35
- package/dist/components/table/components/TableLoadingBody.d.ts +0 -9
- package/dist/components/table/components/TableLoadingBody.js +0 -29
|
@@ -5,7 +5,7 @@ var styles = require('./Card.module.css');
|
|
|
5
5
|
var CardMeta = require('./components/CardMeta');
|
|
6
6
|
var Headline = require('../headline/Headline');
|
|
7
7
|
var Hyperlink = require('../hyperlink/Hyperlink');
|
|
8
|
-
var
|
|
8
|
+
var SkeletonLoader = require('../skeleton-loader/SkeletonLoader');
|
|
9
9
|
|
|
10
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
11
|
|
|
@@ -52,7 +52,7 @@ function CardImpl({
|
|
|
52
52
|
children,
|
|
53
53
|
link,
|
|
54
54
|
width,
|
|
55
|
-
headlineSize =
|
|
55
|
+
headlineSize = 3,
|
|
56
56
|
truncateTitle = false
|
|
57
57
|
}) {
|
|
58
58
|
var _a;
|
|
@@ -76,7 +76,7 @@ function CardImpl({
|
|
|
76
76
|
Headline.Headline,
|
|
77
77
|
{
|
|
78
78
|
severity,
|
|
79
|
-
marker: headerMarker,
|
|
79
|
+
marker: Boolean(severity) && headerMarker,
|
|
80
80
|
icon: headerIcon,
|
|
81
81
|
addition: headerAddition,
|
|
82
82
|
subheader,
|
|
@@ -89,10 +89,7 @@ function CardImpl({
|
|
|
89
89
|
) : null,
|
|
90
90
|
headerMeta ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.headerMeta, children: headerMeta }) : null
|
|
91
91
|
] }) : null,
|
|
92
|
-
loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.
|
|
93
|
-
/* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem.SkeletonLoaderItem, {}),
|
|
94
|
-
/* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem.SkeletonLoaderItem, { width: "100%" })
|
|
95
|
-
] }, index)) }) : null,
|
|
92
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.loadingBody, "aria-busy": "true", "aria-live": "polite", children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoader.SkeletonLoader, { type: "squares", rows: 1, columns: 1 }) }) : null,
|
|
96
93
|
showSection ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.section, children: [
|
|
97
94
|
showSectionDivider ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.sectionDivider }) : null,
|
|
98
95
|
sectionTitle ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.sectionTitle, children: sectionTitle }) : null
|
|
@@ -3,7 +3,7 @@ import styles from './Card.module.css';
|
|
|
3
3
|
import { CardMetaRow, CardMeta } from './components/CardMeta';
|
|
4
4
|
import { Headline } from '../headline/Headline';
|
|
5
5
|
import { Hyperlink } from '../hyperlink/Hyperlink';
|
|
6
|
-
import {
|
|
6
|
+
import { SkeletonLoader } from '../skeleton-loader/SkeletonLoader';
|
|
7
7
|
|
|
8
8
|
function getInnerPlacementClass(imgPlacement, s) {
|
|
9
9
|
switch (imgPlacement) {
|
|
@@ -46,7 +46,7 @@ function CardImpl({
|
|
|
46
46
|
children,
|
|
47
47
|
link,
|
|
48
48
|
width,
|
|
49
|
-
headlineSize =
|
|
49
|
+
headlineSize = 3,
|
|
50
50
|
truncateTitle = false
|
|
51
51
|
}) {
|
|
52
52
|
var _a;
|
|
@@ -70,7 +70,7 @@ function CardImpl({
|
|
|
70
70
|
Headline,
|
|
71
71
|
{
|
|
72
72
|
severity,
|
|
73
|
-
marker: headerMarker,
|
|
73
|
+
marker: Boolean(severity) && headerMarker,
|
|
74
74
|
icon: headerIcon,
|
|
75
75
|
addition: headerAddition,
|
|
76
76
|
subheader,
|
|
@@ -83,10 +83,7 @@ function CardImpl({
|
|
|
83
83
|
) : null,
|
|
84
84
|
headerMeta ? /* @__PURE__ */ jsx("div", { className: styles.headerMeta, children: headerMeta }) : null
|
|
85
85
|
] }) : null,
|
|
86
|
-
loading ? /* @__PURE__ */ jsx("div", { className: styles.
|
|
87
|
-
/* @__PURE__ */ jsx(SkeletonLoaderItem, {}),
|
|
88
|
-
/* @__PURE__ */ jsx(SkeletonLoaderItem, { width: "100%" })
|
|
89
|
-
] }, index)) }) : null,
|
|
86
|
+
loading ? /* @__PURE__ */ jsx("div", { className: styles.loadingBody, "aria-busy": "true", "aria-live": "polite", children: /* @__PURE__ */ jsx(SkeletonLoader, { type: "squares", rows: 1, columns: 1 }) }) : null,
|
|
90
87
|
showSection ? /* @__PURE__ */ jsxs("div", { className: styles.section, children: [
|
|
91
88
|
showSectionDivider ? /* @__PURE__ */ jsx("div", { className: styles.sectionDivider }) : null,
|
|
92
89
|
sectionTitle ? /* @__PURE__ */ jsx("div", { className: styles.sectionTitle, children: sectionTitle }) : null
|
|
@@ -159,16 +159,11 @@
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
/* Loading */
|
|
162
|
-
.
|
|
162
|
+
.loadingBody {
|
|
163
163
|
display: flex;
|
|
164
|
-
flex
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
.loadingRow {
|
|
169
|
-
display: flex;
|
|
170
|
-
flex-direction: column;
|
|
171
|
-
gap: var(--spacing-sm);
|
|
164
|
+
flex: 1 1 auto;
|
|
165
|
+
min-width: 0;
|
|
166
|
+
min-height: 180px;
|
|
172
167
|
}
|
|
173
168
|
|
|
174
169
|
/* Responsive */
|
|
@@ -49,6 +49,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
|
|
|
49
49
|
const listboxId = react.useId();
|
|
50
50
|
const popoverRef = react.useRef(null);
|
|
51
51
|
const internalInputRef = react.useRef(null);
|
|
52
|
+
const onSearchRef = react.useRef(onSearch);
|
|
52
53
|
react.useEffect(() => {
|
|
53
54
|
if (typeof ref === "function") {
|
|
54
55
|
ref(internalInputRef.current);
|
|
@@ -62,18 +63,22 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
|
|
|
62
63
|
if (next !== draft) setDraft(next);
|
|
63
64
|
}, [value]);
|
|
64
65
|
react.useEffect(() => {
|
|
65
|
-
|
|
66
|
+
onSearchRef.current = onSearch;
|
|
67
|
+
}, [onSearch]);
|
|
68
|
+
react.useEffect(() => {
|
|
69
|
+
if (!onSearchRef.current) return;
|
|
66
70
|
if (!debounce) {
|
|
67
71
|
setSearchQuery(draft);
|
|
68
|
-
|
|
72
|
+
onSearchRef.current(draft);
|
|
69
73
|
return;
|
|
70
74
|
}
|
|
71
75
|
const handler = setTimeout(() => {
|
|
76
|
+
var _a2;
|
|
72
77
|
setSearchQuery(draft);
|
|
73
|
-
|
|
78
|
+
(_a2 = onSearchRef.current) == null ? void 0 : _a2.call(onSearchRef, draft);
|
|
74
79
|
}, debounceMs);
|
|
75
80
|
return () => clearTimeout(handler);
|
|
76
|
-
}, [draft,
|
|
81
|
+
}, [draft, debounce, debounceMs]);
|
|
77
82
|
react.useEffect(() => {
|
|
78
83
|
function handleKeyDown(event) {
|
|
79
84
|
var _a2;
|
|
@@ -43,6 +43,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
|
|
|
43
43
|
const listboxId = useId();
|
|
44
44
|
const popoverRef = useRef(null);
|
|
45
45
|
const internalInputRef = useRef(null);
|
|
46
|
+
const onSearchRef = useRef(onSearch);
|
|
46
47
|
useEffect(() => {
|
|
47
48
|
if (typeof ref === "function") {
|
|
48
49
|
ref(internalInputRef.current);
|
|
@@ -56,18 +57,22 @@ const SearchBox = forwardRef(function SearchBoxInner({
|
|
|
56
57
|
if (next !== draft) setDraft(next);
|
|
57
58
|
}, [value]);
|
|
58
59
|
useEffect(() => {
|
|
59
|
-
|
|
60
|
+
onSearchRef.current = onSearch;
|
|
61
|
+
}, [onSearch]);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!onSearchRef.current) return;
|
|
60
64
|
if (!debounce) {
|
|
61
65
|
setSearchQuery(draft);
|
|
62
|
-
|
|
66
|
+
onSearchRef.current(draft);
|
|
63
67
|
return;
|
|
64
68
|
}
|
|
65
69
|
const handler = setTimeout(() => {
|
|
70
|
+
var _a2;
|
|
66
71
|
setSearchQuery(draft);
|
|
67
|
-
|
|
72
|
+
(_a2 = onSearchRef.current) == null ? void 0 : _a2.call(onSearchRef, draft);
|
|
68
73
|
}, debounceMs);
|
|
69
74
|
return () => clearTimeout(handler);
|
|
70
|
-
}, [draft,
|
|
75
|
+
}, [draft, debounce, debounceMs]);
|
|
71
76
|
useEffect(() => {
|
|
72
77
|
function handleKeyDown(event) {
|
|
73
78
|
var _a2;
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
--h: var(--skeleton-height, 14px);
|
|
3
3
|
--r: var(--border-radius-md, 6px);
|
|
4
4
|
--speed: var(--skeleton-speed, 1.2s);
|
|
5
|
-
--skeleton-base: var(--opac-bg-
|
|
6
|
-
--skeleton-sheen: var(--opac-bg-
|
|
5
|
+
--skeleton-base: var(--opac-bg-default);
|
|
6
|
+
--skeleton-sheen: var(--opac-bg-light);
|
|
7
|
+
--skeleton-sheen-soft: color-mix(in srgb, var(--skeleton-sheen) 60%, var(--skeleton-base));
|
|
7
8
|
position: relative;
|
|
8
9
|
display: block;
|
|
9
10
|
inline-size: var(--width, 100%);
|
|
@@ -14,17 +15,20 @@
|
|
|
14
15
|
border-radius: var(--r);
|
|
15
16
|
background: linear-gradient(
|
|
16
17
|
90deg,
|
|
17
|
-
var(--skeleton-
|
|
18
|
-
var(--skeleton-base)
|
|
19
|
-
var(--skeleton-sheen)
|
|
18
|
+
var(--skeleton-base) 0%,
|
|
19
|
+
var(--skeleton-base) 34%,
|
|
20
|
+
var(--skeleton-sheen-soft) 45%,
|
|
21
|
+
var(--skeleton-sheen) 50%,
|
|
22
|
+
var(--skeleton-sheen-soft) 55%,
|
|
23
|
+
var(--skeleton-base) 66%,
|
|
20
24
|
var(--skeleton-base) 100%
|
|
21
25
|
);
|
|
22
|
-
background-size:
|
|
26
|
+
background-size: 240% 100%;
|
|
23
27
|
animation: shimmer var(--speed) linear infinite;
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
.invert {
|
|
27
|
-
--skeleton-base: var(--opac-bg-
|
|
31
|
+
--skeleton-base: var(--opac-bg-default-invert);
|
|
28
32
|
--skeleton-sheen: var(--opac-bg-light-invert);
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var Pagination = require('../../components/pagination/Pagination');
|
|
7
|
+
var SkeletonLoader = require('../../components/skeleton-loader/SkeletonLoader');
|
|
7
8
|
var useViewportFill = require('../../hooks/useViewportFill');
|
|
8
9
|
var EmptyState = require('./components/empty-state/EmptyState');
|
|
9
10
|
var TableBody = require('./components/TableBody');
|
|
10
11
|
var TableHeader = require('./components/TableHeader');
|
|
11
|
-
var TableLoadingBody = require('./components/TableLoadingBody');
|
|
12
12
|
var table_classes = require('./table.classes');
|
|
13
13
|
var styles = require('./Table.module.css');
|
|
14
14
|
var table_utils = require('./table.utils');
|
|
@@ -51,6 +51,7 @@ function Table({
|
|
|
51
51
|
pageSizeOptions,
|
|
52
52
|
showHeader = true,
|
|
53
53
|
getRowSeverity,
|
|
54
|
+
getContextMenuItems,
|
|
54
55
|
onRowClick,
|
|
55
56
|
onRowMouseEnter,
|
|
56
57
|
onRowSelect,
|
|
@@ -64,6 +65,7 @@ function Table({
|
|
|
64
65
|
const internalTableRootRef = react.useRef(null);
|
|
65
66
|
const tableRootRefWrapper = react.useRef(tableRootRef);
|
|
66
67
|
const hasSelection = Boolean(selectedRows && onRowSelect);
|
|
68
|
+
const hasContextMenu = Boolean(getContextMenuItems);
|
|
67
69
|
const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
|
|
68
70
|
const paginationOffset = hasPagination ? 72 : 0;
|
|
69
71
|
const { style: viewportFillStyle, maxHeight } = useViewportFill.useViewportFill(internalTableRootRef, {
|
|
@@ -86,7 +88,7 @@ function Table({
|
|
|
86
88
|
},
|
|
87
89
|
[onPageChange]
|
|
88
90
|
);
|
|
89
|
-
const bodyContent =
|
|
91
|
+
const bodyContent = /* @__PURE__ */ jsxRuntime.jsx(
|
|
90
92
|
TableBody.TableBody,
|
|
91
93
|
{
|
|
92
94
|
data,
|
|
@@ -99,6 +101,7 @@ function Table({
|
|
|
99
101
|
selectionInputName,
|
|
100
102
|
viewMode,
|
|
101
103
|
getRowSeverity,
|
|
104
|
+
getContextMenuItems,
|
|
102
105
|
onRowClick,
|
|
103
106
|
onRowMouseEnter,
|
|
104
107
|
onRowSelect
|
|
@@ -139,7 +142,7 @@ function Table({
|
|
|
139
142
|
ref: setTableRootRef,
|
|
140
143
|
className: styles__default.default.tableScroll,
|
|
141
144
|
style: fillViewportActive ? viewportFillStyle : !containScrolling ? { overflow: "visible" } : void 0,
|
|
142
|
-
children: !data.length
|
|
145
|
+
children: loading && !data.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.emptyStateSlot, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoader.SkeletonLoader, { type: "table", rows: 5, columns: 3 }) }) : !data.length ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.emptyStateSlot, children: /* @__PURE__ */ jsxRuntime.jsx(EmptyState.TableEmptyState, { config: emptyConfig }) }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
143
146
|
"table",
|
|
144
147
|
{
|
|
145
148
|
className: styles__default.default.tableElement,
|
|
@@ -155,13 +158,15 @@ function Table({
|
|
|
155
158
|
style: column.width != null ? { width: column.width } : void 0
|
|
156
159
|
},
|
|
157
160
|
column.id
|
|
158
|
-
))
|
|
161
|
+
)),
|
|
162
|
+
hasContextMenu ? /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: table_utils.CONTEXT_MENU_COLUMN_PX } }) : null
|
|
159
163
|
] }),
|
|
160
164
|
showHeader && /* @__PURE__ */ jsxRuntime.jsx(
|
|
161
165
|
TableHeader.TableHeader,
|
|
162
166
|
{
|
|
163
167
|
columns: visibleColumns,
|
|
164
168
|
hasSelection,
|
|
169
|
+
hasContextMenu,
|
|
165
170
|
selectionMode,
|
|
166
171
|
allRowsSelected,
|
|
167
172
|
onSelectAllRows,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { JSX } from 'react';
|
|
2
2
|
import type { TableProps } from './Table.types';
|
|
3
|
-
export declare function Table<T extends Record<string, any>>({ data, dataKey, columns, selectedRows, selectionMode, allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant, size, viewMode, striped, fillViewport, fillViewportBottomOffset, containScrolling, stickyHeader, tableWidth, tableRootRef, measuringLayout, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement, showFirstLast, showGoToPage, showPageSize, pageSizeOptions, showHeader, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
|
|
3
|
+
export declare function Table<T extends Record<string, any>>({ data, dataKey, columns, selectedRows, selectionMode, allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant, size, viewMode, striped, fillViewport, fillViewportBottomOffset, containScrolling, stickyHeader, tableWidth, tableRootRef, measuringLayout, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement, showFirstLast, showGoToPage, showPageSize, pageSizeOptions, showHeader, getRowSeverity, getContextMenuItems, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
|
|
4
4
|
export type { ColumnItem } from './Table.types';
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import { useMemo, useId, useRef, useCallback } from 'react';
|
|
4
4
|
import { Pagination } from '../../components/pagination/Pagination';
|
|
5
|
+
import { SkeletonLoader } from '../../components/skeleton-loader/SkeletonLoader';
|
|
5
6
|
import { useViewportFill } from '../../hooks/useViewportFill';
|
|
6
7
|
import { TableEmptyState } from './components/empty-state/EmptyState';
|
|
7
8
|
import { TableBody } from './components/TableBody';
|
|
8
9
|
import { TableHeader } from './components/TableHeader';
|
|
9
|
-
import { TableLoadingBody } from './components/TableLoadingBody';
|
|
10
10
|
import { cx } from './table.classes';
|
|
11
11
|
import styles from './Table.module.css';
|
|
12
|
-
import { getVisibleColumns, SELECTION_COLUMN_PX } from './table.utils';
|
|
12
|
+
import { getVisibleColumns, SELECTION_COLUMN_PX, CONTEXT_MENU_COLUMN_PX } from './table.utils';
|
|
13
13
|
|
|
14
14
|
function Table({
|
|
15
15
|
data,
|
|
@@ -45,6 +45,7 @@ function Table({
|
|
|
45
45
|
pageSizeOptions,
|
|
46
46
|
showHeader = true,
|
|
47
47
|
getRowSeverity,
|
|
48
|
+
getContextMenuItems,
|
|
48
49
|
onRowClick,
|
|
49
50
|
onRowMouseEnter,
|
|
50
51
|
onRowSelect,
|
|
@@ -58,6 +59,7 @@ function Table({
|
|
|
58
59
|
const internalTableRootRef = useRef(null);
|
|
59
60
|
const tableRootRefWrapper = useRef(tableRootRef);
|
|
60
61
|
const hasSelection = Boolean(selectedRows && onRowSelect);
|
|
62
|
+
const hasContextMenu = Boolean(getContextMenuItems);
|
|
61
63
|
const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
|
|
62
64
|
const paginationOffset = hasPagination ? 72 : 0;
|
|
63
65
|
const { style: viewportFillStyle, maxHeight } = useViewportFill(internalTableRootRef, {
|
|
@@ -80,7 +82,7 @@ function Table({
|
|
|
80
82
|
},
|
|
81
83
|
[onPageChange]
|
|
82
84
|
);
|
|
83
|
-
const bodyContent =
|
|
85
|
+
const bodyContent = /* @__PURE__ */ jsx(
|
|
84
86
|
TableBody,
|
|
85
87
|
{
|
|
86
88
|
data,
|
|
@@ -93,6 +95,7 @@ function Table({
|
|
|
93
95
|
selectionInputName,
|
|
94
96
|
viewMode,
|
|
95
97
|
getRowSeverity,
|
|
98
|
+
getContextMenuItems,
|
|
96
99
|
onRowClick,
|
|
97
100
|
onRowMouseEnter,
|
|
98
101
|
onRowSelect
|
|
@@ -133,7 +136,7 @@ function Table({
|
|
|
133
136
|
ref: setTableRootRef,
|
|
134
137
|
className: styles.tableScroll,
|
|
135
138
|
style: fillViewportActive ? viewportFillStyle : !containScrolling ? { overflow: "visible" } : void 0,
|
|
136
|
-
children: !data.length
|
|
139
|
+
children: loading && !data.length ? /* @__PURE__ */ jsx("div", { className: styles.emptyStateSlot, children: /* @__PURE__ */ jsx(SkeletonLoader, { type: "table", rows: 5, columns: 3 }) }) : !data.length ? /* @__PURE__ */ jsx("div", { className: styles.emptyStateSlot, children: /* @__PURE__ */ jsx(TableEmptyState, { config: emptyConfig }) }) : /* @__PURE__ */ jsxs(
|
|
137
140
|
"table",
|
|
138
141
|
{
|
|
139
142
|
className: styles.tableElement,
|
|
@@ -149,13 +152,15 @@ function Table({
|
|
|
149
152
|
style: column.width != null ? { width: column.width } : void 0
|
|
150
153
|
},
|
|
151
154
|
column.id
|
|
152
|
-
))
|
|
155
|
+
)),
|
|
156
|
+
hasContextMenu ? /* @__PURE__ */ jsx("col", { style: { width: CONTEXT_MENU_COLUMN_PX } }) : null
|
|
153
157
|
] }),
|
|
154
158
|
showHeader && /* @__PURE__ */ jsx(
|
|
155
159
|
TableHeader,
|
|
156
160
|
{
|
|
157
161
|
columns: visibleColumns,
|
|
158
162
|
hasSelection,
|
|
163
|
+
hasContextMenu,
|
|
159
164
|
selectionMode,
|
|
160
165
|
allRowsSelected,
|
|
161
166
|
onSelectAllRows,
|
|
@@ -241,6 +241,14 @@
|
|
|
241
241
|
line-height: 0;
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
+
.headerCell.contextMenuCell,
|
|
245
|
+
.cell.contextMenuCell {
|
|
246
|
+
inline-size: 1%;
|
|
247
|
+
white-space: nowrap;
|
|
248
|
+
padding-inline: var(--spacing-2xs);
|
|
249
|
+
overflow: visible;
|
|
250
|
+
}
|
|
251
|
+
|
|
244
252
|
.headerCell.selectionCell {
|
|
245
253
|
padding-block: var(--spacing-xxs);
|
|
246
254
|
vertical-align: middle;
|
|
@@ -251,6 +259,15 @@
|
|
|
251
259
|
padding-block: var(--spacing-xxs);
|
|
252
260
|
}
|
|
253
261
|
|
|
262
|
+
.headerCell.contextMenuHeaderCell {
|
|
263
|
+
padding-block: var(--spacing-xxs);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
.cell.contextMenuCell {
|
|
267
|
+
vertical-align: top;
|
|
268
|
+
padding-block: var(--spacing-2xs);
|
|
269
|
+
}
|
|
270
|
+
|
|
254
271
|
.selectionHitArea {
|
|
255
272
|
display: inline-flex;
|
|
256
273
|
align-items: flex-start;
|
|
@@ -475,6 +492,10 @@
|
|
|
475
492
|
text-align: right;
|
|
476
493
|
}
|
|
477
494
|
|
|
495
|
+
.contextMenuCellContent {
|
|
496
|
+
justify-content: flex-end;
|
|
497
|
+
}
|
|
498
|
+
|
|
478
499
|
/* vertical alignment inside content wrapper */
|
|
479
500
|
.cellContent[data-vertical-align='top'] {
|
|
480
501
|
align-items: flex-start;
|
|
@@ -535,6 +556,10 @@
|
|
|
535
556
|
text-overflow: clip;
|
|
536
557
|
}
|
|
537
558
|
|
|
559
|
+
.contextMenuTrigger {
|
|
560
|
+
color: var(--color-fg-subtle);
|
|
561
|
+
}
|
|
562
|
+
|
|
538
563
|
.severityTable {
|
|
539
564
|
--row-rail-width: 2px;
|
|
540
565
|
--row-rail-inset-block: 1px;
|
|
@@ -24,6 +24,14 @@ export type HeaderExtrasArgs<T> = {
|
|
|
24
24
|
column: ColumnItem<T>;
|
|
25
25
|
index: number;
|
|
26
26
|
};
|
|
27
|
+
export type TableContextMenuItem = {
|
|
28
|
+
label: ReactNode;
|
|
29
|
+
onClick: () => void;
|
|
30
|
+
active?: boolean;
|
|
31
|
+
selected?: boolean;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
variant?: 'default' | 'danger';
|
|
34
|
+
};
|
|
27
35
|
export type StickyHeader = false | 'app-header' | number;
|
|
28
36
|
export type TableVariant = 'primary' | 'embedded';
|
|
29
37
|
export type SortDirection = 'asc' | 'desc' | null;
|
|
@@ -61,6 +69,11 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
|
|
|
61
69
|
pageSizeOptions?: number[];
|
|
62
70
|
showHeader?: boolean;
|
|
63
71
|
getRowSeverity?: (row: T) => Severity | undefined;
|
|
72
|
+
getContextMenuItems?: (args: {
|
|
73
|
+
row: T;
|
|
74
|
+
rowId: string | number;
|
|
75
|
+
open: () => void;
|
|
76
|
+
}) => TableContextMenuItem[];
|
|
64
77
|
onRowClick?: (row: T) => void;
|
|
65
78
|
onRowMouseEnter?: (row: T) => void;
|
|
66
79
|
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
@@ -116,11 +116,20 @@ function TanstackTable(props) {
|
|
|
116
116
|
return tanstackTable_utils.buildDistributedColumnWidths({
|
|
117
117
|
table,
|
|
118
118
|
hasSelection: Boolean(selectedRows && onRowSelect && dataKey),
|
|
119
|
+
hasContextMenu: Boolean(tableProps.getContextMenuItems),
|
|
119
120
|
defaultMinPx: 80,
|
|
120
121
|
columnSizing,
|
|
121
122
|
availableWidth
|
|
122
123
|
});
|
|
123
|
-
}, [
|
|
124
|
+
}, [
|
|
125
|
+
table,
|
|
126
|
+
selectedRows,
|
|
127
|
+
onRowSelect,
|
|
128
|
+
dataKey,
|
|
129
|
+
tableProps.getContextMenuItems,
|
|
130
|
+
columnSizing,
|
|
131
|
+
availableWidth
|
|
132
|
+
]);
|
|
124
133
|
const initialLayoutReady = availableWidth != null;
|
|
125
134
|
const resolvedLayout = React__namespace.useMemo(() => {
|
|
126
135
|
const next = {};
|
|
@@ -91,11 +91,20 @@ function TanstackTable(props) {
|
|
|
91
91
|
return buildDistributedColumnWidths({
|
|
92
92
|
table,
|
|
93
93
|
hasSelection: Boolean(selectedRows && onRowSelect && dataKey),
|
|
94
|
+
hasContextMenu: Boolean(tableProps.getContextMenuItems),
|
|
94
95
|
defaultMinPx: 80,
|
|
95
96
|
columnSizing,
|
|
96
97
|
availableWidth
|
|
97
98
|
});
|
|
98
|
-
}, [
|
|
99
|
+
}, [
|
|
100
|
+
table,
|
|
101
|
+
selectedRows,
|
|
102
|
+
onRowSelect,
|
|
103
|
+
dataKey,
|
|
104
|
+
tableProps.getContextMenuItems,
|
|
105
|
+
columnSizing,
|
|
106
|
+
availableWidth
|
|
107
|
+
]);
|
|
99
108
|
const initialLayoutReady = availableWidth != null;
|
|
100
109
|
const resolvedLayout = React.useMemo(() => {
|
|
101
110
|
const next = {};
|
|
@@ -20,6 +20,7 @@ function TableBody({
|
|
|
20
20
|
selectionInputName,
|
|
21
21
|
viewMode,
|
|
22
22
|
getRowSeverity,
|
|
23
|
+
getContextMenuItems,
|
|
23
24
|
onRowClick,
|
|
24
25
|
onRowMouseEnter,
|
|
25
26
|
onRowSelect
|
|
@@ -38,6 +39,7 @@ function TableBody({
|
|
|
38
39
|
selectionInputName,
|
|
39
40
|
viewMode,
|
|
40
41
|
getRowSeverity,
|
|
42
|
+
getContextMenuItems,
|
|
41
43
|
onRowClick,
|
|
42
44
|
onRowMouseEnter,
|
|
43
45
|
onRowSelect
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { ViewMode } from '../../../hooks/useTableSettings';
|
|
3
|
-
import type { ColumnItem } from '../Table.types';
|
|
3
|
+
import type { ColumnItem, TableContextMenuItem } from '../Table.types';
|
|
4
4
|
type Props<T extends Record<string, any>> = {
|
|
5
5
|
data: T[];
|
|
6
6
|
dataKey: keyof T;
|
|
@@ -12,9 +12,14 @@ type Props<T extends Record<string, any>> = {
|
|
|
12
12
|
selectionInputName: string;
|
|
13
13
|
viewMode?: ViewMode;
|
|
14
14
|
getRowSeverity?: (row: T) => any;
|
|
15
|
+
getContextMenuItems?: (args: {
|
|
16
|
+
row: T;
|
|
17
|
+
rowId: string | number;
|
|
18
|
+
open: () => void;
|
|
19
|
+
}) => TableContextMenuItem[];
|
|
15
20
|
onRowClick?: (row: T) => void;
|
|
16
21
|
onRowMouseEnter?: (row: T) => void;
|
|
17
22
|
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
18
23
|
};
|
|
19
|
-
export declare function TableBody<T extends Record<string, any>>({ data, dataKey, columns, striped, selectedRows, hasSelection, selectionMode, selectionInputName, viewMode, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, }: Props<T>): ReactNode;
|
|
24
|
+
export declare function TableBody<T extends Record<string, any>>({ data, dataKey, columns, striped, selectedRows, hasSelection, selectionMode, selectionInputName, viewMode, getRowSeverity, getContextMenuItems, onRowClick, onRowMouseEnter, onRowSelect, }: Props<T>): ReactNode;
|
|
20
25
|
export {};
|
|
@@ -14,6 +14,7 @@ function TableBody({
|
|
|
14
14
|
selectionInputName,
|
|
15
15
|
viewMode,
|
|
16
16
|
getRowSeverity,
|
|
17
|
+
getContextMenuItems,
|
|
17
18
|
onRowClick,
|
|
18
19
|
onRowMouseEnter,
|
|
19
20
|
onRowSelect
|
|
@@ -32,6 +33,7 @@ function TableBody({
|
|
|
32
33
|
selectionInputName,
|
|
33
34
|
viewMode,
|
|
34
35
|
getRowSeverity,
|
|
36
|
+
getContextMenuItems,
|
|
35
37
|
onRowClick,
|
|
36
38
|
onRowMouseEnter,
|
|
37
39
|
onRowSelect
|
|
@@ -12,6 +12,7 @@ var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
|
12
12
|
function TableHeader({
|
|
13
13
|
columns,
|
|
14
14
|
hasSelection,
|
|
15
|
+
hasContextMenu,
|
|
15
16
|
selectionMode,
|
|
16
17
|
allRowsSelected,
|
|
17
18
|
onSelectAllRows,
|
|
@@ -47,7 +48,15 @@ function TableHeader({
|
|
|
47
48
|
extraContent: headerExtras == null ? void 0 : headerExtras({ column, index })
|
|
48
49
|
},
|
|
49
50
|
column.id
|
|
50
|
-
))
|
|
51
|
+
)),
|
|
52
|
+
hasContextMenu ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
53
|
+
"th",
|
|
54
|
+
{
|
|
55
|
+
className: [styles__default.default.headerCell, styles__default.default.contextMenuCell, styles__default.default.contextMenuHeaderCell].filter(Boolean).join(" "),
|
|
56
|
+
scope: "col",
|
|
57
|
+
"aria-label": "R\xE6kkehandlinger"
|
|
58
|
+
}
|
|
59
|
+
) : null
|
|
51
60
|
] })
|
|
52
61
|
}
|
|
53
62
|
);
|
|
@@ -3,6 +3,7 @@ import type { ColumnItem, HeaderExtrasArgs, SortDirection } from '../Table.types
|
|
|
3
3
|
type Props<T> = {
|
|
4
4
|
columns: ColumnItem<T>[];
|
|
5
5
|
hasSelection: boolean;
|
|
6
|
+
hasContextMenu: boolean;
|
|
6
7
|
selectionMode: 'single' | 'multiple';
|
|
7
8
|
allRowsSelected?: boolean;
|
|
8
9
|
onSelectAllRows?: (isSelected: boolean) => void;
|
|
@@ -12,5 +13,5 @@ type Props<T> = {
|
|
|
12
13
|
headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
|
|
13
14
|
stickyTop?: string;
|
|
14
15
|
};
|
|
15
|
-
export declare function TableHeader<T>({ columns, hasSelection, selectionMode, allRowsSelected, onSelectAllRows, sortById, sortDirection, onSortChange, headerExtras, stickyTop, }: Props<T>): React.ReactNode;
|
|
16
|
+
export declare function TableHeader<T>({ columns, hasSelection, hasContextMenu, selectionMode, allRowsSelected, onSelectAllRows, sortById, sortDirection, onSortChange, headerExtras, stickyTop, }: Props<T>): React.ReactNode;
|
|
16
17
|
export {};
|
|
@@ -6,6 +6,7 @@ import styles from '../Table.module.css';
|
|
|
6
6
|
function TableHeader({
|
|
7
7
|
columns,
|
|
8
8
|
hasSelection,
|
|
9
|
+
hasContextMenu,
|
|
9
10
|
selectionMode,
|
|
10
11
|
allRowsSelected,
|
|
11
12
|
onSelectAllRows,
|
|
@@ -41,7 +42,15 @@ function TableHeader({
|
|
|
41
42
|
extraContent: headerExtras == null ? void 0 : headerExtras({ column, index })
|
|
42
43
|
},
|
|
43
44
|
column.id
|
|
44
|
-
))
|
|
45
|
+
)),
|
|
46
|
+
hasContextMenu ? /* @__PURE__ */ jsx(
|
|
47
|
+
"th",
|
|
48
|
+
{
|
|
49
|
+
className: [styles.headerCell, styles.contextMenuCell, styles.contextMenuHeaderCell].filter(Boolean).join(" "),
|
|
50
|
+
scope: "col",
|
|
51
|
+
"aria-label": "R\xE6kkehandlinger"
|
|
52
|
+
}
|
|
53
|
+
) : null
|
|
45
54
|
] })
|
|
46
55
|
}
|
|
47
56
|
);
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var lucideReact = require('lucide-react');
|
|
4
5
|
var Checkbox = require('../../../components/forms/checkbox/Checkbox');
|
|
5
6
|
var RadioButton = require('../../../components/forms/radio-buttons/RadioButton');
|
|
7
|
+
var Popover = require('../../../components/popover/Popover');
|
|
6
8
|
var severity = require('../../../constants/severity');
|
|
9
|
+
var Button = require('../../button/Button');
|
|
10
|
+
var Menu = require('../../menu/Menu');
|
|
7
11
|
var useTableRowInteractions = require('../hooks/useTableRowInteractions');
|
|
8
12
|
var table_classes = require('../table.classes');
|
|
9
13
|
var styles = require('../Table.module.css');
|
|
@@ -23,6 +27,7 @@ function TableRow({
|
|
|
23
27
|
selectionInputName,
|
|
24
28
|
viewMode,
|
|
25
29
|
getRowSeverity,
|
|
30
|
+
getContextMenuItems,
|
|
26
31
|
onRowClick,
|
|
27
32
|
onRowMouseEnter,
|
|
28
33
|
onRowSelect
|
|
@@ -31,6 +36,11 @@ function TableRow({
|
|
|
31
36
|
const isSelected = (_a = selectedRows == null ? void 0 : selectedRows.has(rowId)) != null ? _a : false;
|
|
32
37
|
const rowSeverity = getRowSeverity == null ? void 0 : getRowSeverity(row);
|
|
33
38
|
const canSelect = Boolean(selectedRows && onRowSelect);
|
|
39
|
+
const contextMenuItems = getContextMenuItems == null ? void 0 : getContextMenuItems({
|
|
40
|
+
row,
|
|
41
|
+
rowId,
|
|
42
|
+
open: () => onRowClick == null ? void 0 : onRowClick(row)
|
|
43
|
+
});
|
|
34
44
|
const { handleRowClick, handleRowKeyDown } = useTableRowInteractions.useTableRowInteractions({
|
|
35
45
|
row,
|
|
36
46
|
rowId,
|
|
@@ -149,10 +159,74 @@ function TableRow({
|
|
|
149
159
|
},
|
|
150
160
|
column.id
|
|
151
161
|
);
|
|
152
|
-
})
|
|
162
|
+
}),
|
|
163
|
+
(contextMenuItems == null ? void 0 : contextMenuItems.length) ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: table_classes.cx(styles__default.default.cell, styles__default.default.contextMenuCell), "data-row-context-menu": "true", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
164
|
+
"div",
|
|
165
|
+
{
|
|
166
|
+
className: table_classes.cx(styles__default.default.cellContent, styles__default.default.contextMenuCellContent),
|
|
167
|
+
"data-align": "right",
|
|
168
|
+
"data-row-context-menu": "true",
|
|
169
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(RowContextMenu, { row, rowId, items: contextMenuItems })
|
|
170
|
+
}
|
|
171
|
+
) }) : null
|
|
153
172
|
]
|
|
154
173
|
}
|
|
155
174
|
);
|
|
156
175
|
}
|
|
176
|
+
function RowContextMenu({
|
|
177
|
+
row,
|
|
178
|
+
rowId,
|
|
179
|
+
items
|
|
180
|
+
}) {
|
|
181
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
182
|
+
Popover.Popover,
|
|
183
|
+
{
|
|
184
|
+
matchTriggerWidth: false,
|
|
185
|
+
minWidth: "180px",
|
|
186
|
+
trigger: (toggle, _icon, isOpen) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
187
|
+
Button.Button,
|
|
188
|
+
{
|
|
189
|
+
type: "button",
|
|
190
|
+
size: "sm",
|
|
191
|
+
variant: "inline",
|
|
192
|
+
shape: "round",
|
|
193
|
+
className: styles__default.default.contextMenuTrigger,
|
|
194
|
+
"aria-label": `Flere handlinger for r\xE6kke ${String(rowId)}`,
|
|
195
|
+
"aria-haspopup": "menu",
|
|
196
|
+
"aria-expanded": isOpen ? true : false,
|
|
197
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontal, { size: 16 }),
|
|
198
|
+
"data-row-context-menu": "true",
|
|
199
|
+
onClick: (e) => {
|
|
200
|
+
e.stopPropagation();
|
|
201
|
+
toggle(e);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
),
|
|
205
|
+
children: (close) => /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu, { children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
206
|
+
Menu.Menu.Item,
|
|
207
|
+
{
|
|
208
|
+
active: item.active,
|
|
209
|
+
selected: item.selected,
|
|
210
|
+
disabled: item.disabled,
|
|
211
|
+
variant: item.variant,
|
|
212
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
213
|
+
"button",
|
|
214
|
+
{
|
|
215
|
+
type: "button",
|
|
216
|
+
"data-row-context-menu": "true",
|
|
217
|
+
onClick: (e) => {
|
|
218
|
+
e.stopPropagation();
|
|
219
|
+
item.onClick();
|
|
220
|
+
close();
|
|
221
|
+
},
|
|
222
|
+
children: item.label
|
|
223
|
+
}
|
|
224
|
+
)
|
|
225
|
+
},
|
|
226
|
+
index
|
|
227
|
+
)) })
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
}
|
|
157
231
|
|
|
158
232
|
exports.TableRow = TableRow;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { ViewMode } from '../../../hooks/useTableSettings';
|
|
3
|
-
import type { ColumnItem } from '../Table.types';
|
|
3
|
+
import type { ColumnItem, TableContextMenuItem } from '../Table.types';
|
|
4
4
|
type Props<T extends Record<string, any>> = {
|
|
5
5
|
row: T;
|
|
6
6
|
rowId: string | number;
|
|
@@ -11,9 +11,14 @@ type Props<T extends Record<string, any>> = {
|
|
|
11
11
|
selectionInputName: string;
|
|
12
12
|
viewMode?: ViewMode;
|
|
13
13
|
getRowSeverity?: (row: T) => any;
|
|
14
|
+
getContextMenuItems?: (args: {
|
|
15
|
+
row: T;
|
|
16
|
+
rowId: string | number;
|
|
17
|
+
open: () => void;
|
|
18
|
+
}) => TableContextMenuItem[];
|
|
14
19
|
onRowClick?: (row: T) => void;
|
|
15
20
|
onRowMouseEnter?: (row: T) => void;
|
|
16
21
|
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
17
22
|
};
|
|
18
|
-
export declare function TableRow<T extends Record<string, any>>({ row, rowId, columns, selectedRows, hasSelection, selectionMode, selectionInputName, viewMode, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, }: Props<T>): React.ReactNode;
|
|
23
|
+
export declare function TableRow<T extends Record<string, any>>({ row, rowId, columns, selectedRows, hasSelection, selectionMode, selectionInputName, viewMode, getRowSeverity, getContextMenuItems, onRowClick, onRowMouseEnter, onRowSelect, }: Props<T>): React.ReactNode;
|
|
19
24
|
export {};
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { MoreHorizontal } from 'lucide-react';
|
|
2
3
|
import { Checkbox } from '../../../components/forms/checkbox/Checkbox';
|
|
3
4
|
import { RadioButton } from '../../../components/forms/radio-buttons/RadioButton';
|
|
5
|
+
import { Popover } from '../../../components/popover/Popover';
|
|
4
6
|
import { SeverityBgColor } from '../../../constants/severity';
|
|
7
|
+
import { Button } from '../../button/Button';
|
|
8
|
+
import { Menu } from '../../menu/Menu';
|
|
5
9
|
import { useTableRowInteractions } from '../hooks/useTableRowInteractions';
|
|
6
10
|
import { cx } from '../table.classes';
|
|
7
11
|
import styles from '../Table.module.css';
|
|
@@ -17,6 +21,7 @@ function TableRow({
|
|
|
17
21
|
selectionInputName,
|
|
18
22
|
viewMode,
|
|
19
23
|
getRowSeverity,
|
|
24
|
+
getContextMenuItems,
|
|
20
25
|
onRowClick,
|
|
21
26
|
onRowMouseEnter,
|
|
22
27
|
onRowSelect
|
|
@@ -25,6 +30,11 @@ function TableRow({
|
|
|
25
30
|
const isSelected = (_a = selectedRows == null ? void 0 : selectedRows.has(rowId)) != null ? _a : false;
|
|
26
31
|
const rowSeverity = getRowSeverity == null ? void 0 : getRowSeverity(row);
|
|
27
32
|
const canSelect = Boolean(selectedRows && onRowSelect);
|
|
33
|
+
const contextMenuItems = getContextMenuItems == null ? void 0 : getContextMenuItems({
|
|
34
|
+
row,
|
|
35
|
+
rowId,
|
|
36
|
+
open: () => onRowClick == null ? void 0 : onRowClick(row)
|
|
37
|
+
});
|
|
28
38
|
const { handleRowClick, handleRowKeyDown } = useTableRowInteractions({
|
|
29
39
|
row,
|
|
30
40
|
rowId,
|
|
@@ -143,10 +153,74 @@ function TableRow({
|
|
|
143
153
|
},
|
|
144
154
|
column.id
|
|
145
155
|
);
|
|
146
|
-
})
|
|
156
|
+
}),
|
|
157
|
+
(contextMenuItems == null ? void 0 : contextMenuItems.length) ? /* @__PURE__ */ jsx("td", { className: cx(styles.cell, styles.contextMenuCell), "data-row-context-menu": "true", children: /* @__PURE__ */ jsx(
|
|
158
|
+
"div",
|
|
159
|
+
{
|
|
160
|
+
className: cx(styles.cellContent, styles.contextMenuCellContent),
|
|
161
|
+
"data-align": "right",
|
|
162
|
+
"data-row-context-menu": "true",
|
|
163
|
+
children: /* @__PURE__ */ jsx(RowContextMenu, { row, rowId, items: contextMenuItems })
|
|
164
|
+
}
|
|
165
|
+
) }) : null
|
|
147
166
|
]
|
|
148
167
|
}
|
|
149
168
|
);
|
|
150
169
|
}
|
|
170
|
+
function RowContextMenu({
|
|
171
|
+
row,
|
|
172
|
+
rowId,
|
|
173
|
+
items
|
|
174
|
+
}) {
|
|
175
|
+
return /* @__PURE__ */ jsx(
|
|
176
|
+
Popover,
|
|
177
|
+
{
|
|
178
|
+
matchTriggerWidth: false,
|
|
179
|
+
minWidth: "180px",
|
|
180
|
+
trigger: (toggle, _icon, isOpen) => /* @__PURE__ */ jsx(
|
|
181
|
+
Button,
|
|
182
|
+
{
|
|
183
|
+
type: "button",
|
|
184
|
+
size: "sm",
|
|
185
|
+
variant: "inline",
|
|
186
|
+
shape: "round",
|
|
187
|
+
className: styles.contextMenuTrigger,
|
|
188
|
+
"aria-label": `Flere handlinger for r\xE6kke ${String(rowId)}`,
|
|
189
|
+
"aria-haspopup": "menu",
|
|
190
|
+
"aria-expanded": isOpen ? true : false,
|
|
191
|
+
icon: /* @__PURE__ */ jsx(MoreHorizontal, { size: 16 }),
|
|
192
|
+
"data-row-context-menu": "true",
|
|
193
|
+
onClick: (e) => {
|
|
194
|
+
e.stopPropagation();
|
|
195
|
+
toggle(e);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
),
|
|
199
|
+
children: (close) => /* @__PURE__ */ jsx(Menu, { children: items.map((item, index) => /* @__PURE__ */ jsx(
|
|
200
|
+
Menu.Item,
|
|
201
|
+
{
|
|
202
|
+
active: item.active,
|
|
203
|
+
selected: item.selected,
|
|
204
|
+
disabled: item.disabled,
|
|
205
|
+
variant: item.variant,
|
|
206
|
+
children: /* @__PURE__ */ jsx(
|
|
207
|
+
"button",
|
|
208
|
+
{
|
|
209
|
+
type: "button",
|
|
210
|
+
"data-row-context-menu": "true",
|
|
211
|
+
onClick: (e) => {
|
|
212
|
+
e.stopPropagation();
|
|
213
|
+
item.onClick();
|
|
214
|
+
close();
|
|
215
|
+
},
|
|
216
|
+
children: item.label
|
|
217
|
+
}
|
|
218
|
+
)
|
|
219
|
+
},
|
|
220
|
+
index
|
|
221
|
+
)) })
|
|
222
|
+
}
|
|
223
|
+
);
|
|
224
|
+
}
|
|
151
225
|
|
|
152
226
|
export { TableRow };
|
|
@@ -13,9 +13,9 @@ function useTableRowInteractions({
|
|
|
13
13
|
}) {
|
|
14
14
|
const handleRowClick = react.useCallback(
|
|
15
15
|
(e) => {
|
|
16
|
-
var _a;
|
|
16
|
+
var _a, _b;
|
|
17
17
|
const target = e.target;
|
|
18
|
-
if ((_a = target == null ? void 0 : target.closest) == null ? void 0 : _a.call(target, '[data-selection-control="true"]')) {
|
|
18
|
+
if (((_a = target == null ? void 0 : target.closest) == null ? void 0 : _a.call(target, '[data-selection-control="true"]')) || ((_b = target == null ? void 0 : target.closest) == null ? void 0 : _b.call(target, '[data-row-context-menu="true"]'))) {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
if (table_utils.isModifierClick(e) && canSelect) {
|
|
@@ -11,9 +11,9 @@ function useTableRowInteractions({
|
|
|
11
11
|
}) {
|
|
12
12
|
const handleRowClick = useCallback(
|
|
13
13
|
(e) => {
|
|
14
|
-
var _a;
|
|
14
|
+
var _a, _b;
|
|
15
15
|
const target = e.target;
|
|
16
|
-
if ((_a = target == null ? void 0 : target.closest) == null ? void 0 : _a.call(target, '[data-selection-control="true"]')) {
|
|
16
|
+
if (((_a = target == null ? void 0 : target.closest) == null ? void 0 : _a.call(target, '[data-selection-control="true"]')) || ((_b = target == null ? void 0 : target.closest) == null ? void 0 : _b.call(target, '[data-row-context-menu="true"]'))) {
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
if (isModifierClick(e) && canSelect) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const SELECTION_COLUMN_PX = 40;
|
|
4
|
+
const CONTEXT_MENU_COLUMN_PX = 44;
|
|
4
5
|
const DEFAULT_COLUMN_PX = 150;
|
|
5
6
|
function getVisibleColumns(columns) {
|
|
6
7
|
return columns.filter((column) => !column.hidden);
|
|
@@ -44,6 +45,7 @@ function getCellDisplayValue(row, column) {
|
|
|
44
45
|
return empty;
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
exports.CONTEXT_MENU_COLUMN_PX = CONTEXT_MENU_COLUMN_PX;
|
|
47
49
|
exports.DEFAULT_COLUMN_PX = DEFAULT_COLUMN_PX;
|
|
48
50
|
exports.SELECTION_COLUMN_PX = SELECTION_COLUMN_PX;
|
|
49
51
|
exports.getAriaSort = getAriaSort;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { ColumnItem } from './Table.types';
|
|
3
3
|
export declare const SELECTION_COLUMN_PX: 40;
|
|
4
|
+
export declare const CONTEXT_MENU_COLUMN_PX: 44;
|
|
4
5
|
export declare const DEFAULT_COLUMN_PX: 150;
|
|
5
6
|
export type SortDirection = 'asc' | 'desc' | null;
|
|
6
7
|
export declare function getVisibleColumns<T>(columns: Array<ColumnItem<T>>): Array<ColumnItem<T>>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const SELECTION_COLUMN_PX = 40;
|
|
2
|
+
const CONTEXT_MENU_COLUMN_PX = 44;
|
|
2
3
|
const DEFAULT_COLUMN_PX = 150;
|
|
3
4
|
function getVisibleColumns(columns) {
|
|
4
5
|
return columns.filter((column) => !column.hidden);
|
|
@@ -42,4 +43,4 @@ function getCellDisplayValue(row, column) {
|
|
|
42
43
|
return empty;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
export { DEFAULT_COLUMN_PX, SELECTION_COLUMN_PX, getAriaSort, getCellDisplayValue, getHeaderLabel, getNextSortDirection, getVisibleColumns, isActiveSort, isModifierClick, shouldAllowWrap, shouldToggleOnKey };
|
|
46
|
+
export { CONTEXT_MENU_COLUMN_PX, DEFAULT_COLUMN_PX, SELECTION_COLUMN_PX, getAriaSort, getCellDisplayValue, getHeaderLabel, getNextSortDirection, getVisibleColumns, isActiveSort, isModifierClick, shouldAllowWrap, shouldToggleOnKey };
|
|
@@ -93,9 +93,10 @@ function toIntegerTrackWidths(tracks, targetWidth) {
|
|
|
93
93
|
return Object.fromEntries(floored.map((track) => [track.id, track.width]));
|
|
94
94
|
}
|
|
95
95
|
function buildDistributedColumnWidths(args) {
|
|
96
|
-
const { table, hasSelection, defaultMinPx, columnSizing, availableWidth } = args;
|
|
96
|
+
const { table, hasSelection, hasContextMenu, defaultMinPx, columnSizing, availableWidth } = args;
|
|
97
97
|
const leaf = table.getVisibleLeafColumns();
|
|
98
98
|
const selectionWidth = hasSelection ? table_utils.SELECTION_COLUMN_PX : 0;
|
|
99
|
+
const contextMenuWidth = hasContextMenu ? table_utils.CONTEXT_MENU_COLUMN_PX : 0;
|
|
99
100
|
const tracks = leaf.map((c) => {
|
|
100
101
|
var _a, _b, _c, _d;
|
|
101
102
|
const def = c.columnDef;
|
|
@@ -123,7 +124,7 @@ function buildDistributedColumnWidths(args) {
|
|
|
123
124
|
fixed: false
|
|
124
125
|
};
|
|
125
126
|
});
|
|
126
|
-
const fixedWidth = selectionWidth + tracks.reduce((sum, track) => sum + track.width, 0);
|
|
127
|
+
const fixedWidth = selectionWidth + contextMenuWidth + tracks.reduce((sum, track) => sum + track.width, 0);
|
|
127
128
|
let remaining = Math.max(0, availableWidth - fixedWidth);
|
|
128
129
|
let active = tracks.filter(
|
|
129
130
|
(track) => !track.fixed && (track.max == null || track.width < track.max)
|
|
@@ -148,18 +149,19 @@ function buildDistributedColumnWidths(args) {
|
|
|
148
149
|
active = nextActive;
|
|
149
150
|
}
|
|
150
151
|
const floatTrackTotal = tracks.reduce((sum, track) => sum + track.width, 0);
|
|
151
|
-
const maxTrackWidth = availableWidth - selectionWidth;
|
|
152
|
+
const maxTrackWidth = availableWidth - selectionWidth - contextMenuWidth;
|
|
152
153
|
const targetTrackWidth = Math.min(
|
|
153
154
|
floatTrackTotal <= maxTrackWidth ? Math.floor(floatTrackTotal) : Math.ceil(floatTrackTotal),
|
|
154
155
|
maxTrackWidth
|
|
155
156
|
);
|
|
156
157
|
const widths = toIntegerTrackWidths(tracks, targetTrackWidth);
|
|
157
158
|
const totalWidth = Math.min(
|
|
158
|
-
selectionWidth + Object.values(widths).reduce((sum, width) => sum + width, 0),
|
|
159
|
+
selectionWidth + contextMenuWidth + Object.values(widths).reduce((sum, width) => sum + width, 0),
|
|
159
160
|
availableWidth
|
|
160
161
|
);
|
|
161
162
|
return {
|
|
162
163
|
selectionWidth: hasSelection ? table_utils.SELECTION_COLUMN_PX : void 0,
|
|
164
|
+
contextMenuWidth: hasContextMenu ? table_utils.CONTEXT_MENU_COLUMN_PX : void 0,
|
|
163
165
|
widths,
|
|
164
166
|
totalWidth
|
|
165
167
|
};
|
|
@@ -14,11 +14,13 @@ export declare function getSortPropsFromSorting(sorting: SortingState): {
|
|
|
14
14
|
export declare function buildDistributedColumnWidths(args: {
|
|
15
15
|
table: any;
|
|
16
16
|
hasSelection: boolean;
|
|
17
|
+
hasContextMenu: boolean;
|
|
17
18
|
defaultMinPx: number;
|
|
18
19
|
columnSizing: ColumnSizingState;
|
|
19
20
|
availableWidth: number;
|
|
20
21
|
}): {
|
|
21
22
|
selectionWidth?: number;
|
|
23
|
+
contextMenuWidth?: number;
|
|
22
24
|
widths: Record<string, number>;
|
|
23
25
|
totalWidth: number;
|
|
24
26
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_COLUMN_PX, SELECTION_COLUMN_PX } from './table.utils';
|
|
1
|
+
import { DEFAULT_COLUMN_PX, CONTEXT_MENU_COLUMN_PX, SELECTION_COLUMN_PX } from './table.utils';
|
|
2
2
|
|
|
3
3
|
function getColumnId(def, index) {
|
|
4
4
|
const d = def;
|
|
@@ -91,9 +91,10 @@ function toIntegerTrackWidths(tracks, targetWidth) {
|
|
|
91
91
|
return Object.fromEntries(floored.map((track) => [track.id, track.width]));
|
|
92
92
|
}
|
|
93
93
|
function buildDistributedColumnWidths(args) {
|
|
94
|
-
const { table, hasSelection, defaultMinPx, columnSizing, availableWidth } = args;
|
|
94
|
+
const { table, hasSelection, hasContextMenu, defaultMinPx, columnSizing, availableWidth } = args;
|
|
95
95
|
const leaf = table.getVisibleLeafColumns();
|
|
96
96
|
const selectionWidth = hasSelection ? SELECTION_COLUMN_PX : 0;
|
|
97
|
+
const contextMenuWidth = hasContextMenu ? CONTEXT_MENU_COLUMN_PX : 0;
|
|
97
98
|
const tracks = leaf.map((c) => {
|
|
98
99
|
var _a, _b, _c, _d;
|
|
99
100
|
const def = c.columnDef;
|
|
@@ -121,7 +122,7 @@ function buildDistributedColumnWidths(args) {
|
|
|
121
122
|
fixed: false
|
|
122
123
|
};
|
|
123
124
|
});
|
|
124
|
-
const fixedWidth = selectionWidth + tracks.reduce((sum, track) => sum + track.width, 0);
|
|
125
|
+
const fixedWidth = selectionWidth + contextMenuWidth + tracks.reduce((sum, track) => sum + track.width, 0);
|
|
125
126
|
let remaining = Math.max(0, availableWidth - fixedWidth);
|
|
126
127
|
let active = tracks.filter(
|
|
127
128
|
(track) => !track.fixed && (track.max == null || track.width < track.max)
|
|
@@ -146,18 +147,19 @@ function buildDistributedColumnWidths(args) {
|
|
|
146
147
|
active = nextActive;
|
|
147
148
|
}
|
|
148
149
|
const floatTrackTotal = tracks.reduce((sum, track) => sum + track.width, 0);
|
|
149
|
-
const maxTrackWidth = availableWidth - selectionWidth;
|
|
150
|
+
const maxTrackWidth = availableWidth - selectionWidth - contextMenuWidth;
|
|
150
151
|
const targetTrackWidth = Math.min(
|
|
151
152
|
floatTrackTotal <= maxTrackWidth ? Math.floor(floatTrackTotal) : Math.ceil(floatTrackTotal),
|
|
152
153
|
maxTrackWidth
|
|
153
154
|
);
|
|
154
155
|
const widths = toIntegerTrackWidths(tracks, targetTrackWidth);
|
|
155
156
|
const totalWidth = Math.min(
|
|
156
|
-
selectionWidth + Object.values(widths).reduce((sum, width) => sum + width, 0),
|
|
157
|
+
selectionWidth + contextMenuWidth + Object.values(widths).reduce((sum, width) => sum + width, 0),
|
|
157
158
|
availableWidth
|
|
158
159
|
);
|
|
159
160
|
return {
|
|
160
161
|
selectionWidth: hasSelection ? SELECTION_COLUMN_PX : void 0,
|
|
162
|
+
contextMenuWidth: hasContextMenu ? CONTEXT_MENU_COLUMN_PX : void 0,
|
|
161
163
|
widths,
|
|
162
164
|
totalWidth
|
|
163
165
|
};
|
package/package.json
CHANGED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var SkeletonLoaderItem = require('../../../components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem');
|
|
5
|
-
var table_classes = require('../table.classes');
|
|
6
|
-
var styles = require('../Table.module.css');
|
|
7
|
-
|
|
8
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
-
|
|
10
|
-
var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
11
|
-
|
|
12
|
-
function TableLoadingBody({ rows, columns, hasSelection }) {
|
|
13
|
-
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: styles__default.default.body, children: Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: styles__default.default.row, children: [
|
|
14
|
-
hasSelection ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: table_classes.cx(styles__default.default.cell, styles__default.default.selectionCell), children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.cellContent, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem.SkeletonLoaderItem, { height: 20, width: 20 }) }) }) : null,
|
|
15
|
-
columns.map((column) => {
|
|
16
|
-
var _a;
|
|
17
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18
|
-
"td",
|
|
19
|
-
{
|
|
20
|
-
className: table_classes.cx(
|
|
21
|
-
styles__default.default.cell,
|
|
22
|
-
column.divider === "left" && styles__default.default.dividerLeft,
|
|
23
|
-
column.divider === "right" && styles__default.default.dividerRight
|
|
24
|
-
),
|
|
25
|
-
"data-align": (_a = column.align) != null ? _a : "left",
|
|
26
|
-
"data-divider": column.divider,
|
|
27
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.cellContent, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.cellValueEllipsis, children: /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem.SkeletonLoaderItem, { height: 20, width: "100%" }) }) })
|
|
28
|
-
},
|
|
29
|
-
column.id
|
|
30
|
-
);
|
|
31
|
-
})
|
|
32
|
-
] }, `loading-row-${rowIndex}`)) });
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
exports.TableLoadingBody = TableLoadingBody;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import type { ColumnItem } from '../Table.types';
|
|
3
|
-
type Props<T> = {
|
|
4
|
-
rows: number;
|
|
5
|
-
columns: ColumnItem<T>[];
|
|
6
|
-
hasSelection: boolean;
|
|
7
|
-
};
|
|
8
|
-
export declare function TableLoadingBody<T>({ rows, columns, hasSelection }: Props<T>): ReactNode;
|
|
9
|
-
export {};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { SkeletonLoaderItem } from '../../../components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem';
|
|
3
|
-
import { cx } from '../table.classes';
|
|
4
|
-
import styles from '../Table.module.css';
|
|
5
|
-
|
|
6
|
-
function TableLoadingBody({ rows, columns, hasSelection }) {
|
|
7
|
-
return /* @__PURE__ */ jsx("tbody", { className: styles.body, children: Array.from({ length: rows }).map((_, rowIndex) => /* @__PURE__ */ jsxs("tr", { className: styles.row, children: [
|
|
8
|
-
hasSelection ? /* @__PURE__ */ jsx("td", { className: cx(styles.cell, styles.selectionCell), children: /* @__PURE__ */ jsx("div", { className: styles.cellContent, children: /* @__PURE__ */ jsx(SkeletonLoaderItem, { height: 20, width: 20 }) }) }) : null,
|
|
9
|
-
columns.map((column) => {
|
|
10
|
-
var _a;
|
|
11
|
-
return /* @__PURE__ */ jsx(
|
|
12
|
-
"td",
|
|
13
|
-
{
|
|
14
|
-
className: cx(
|
|
15
|
-
styles.cell,
|
|
16
|
-
column.divider === "left" && styles.dividerLeft,
|
|
17
|
-
column.divider === "right" && styles.dividerRight
|
|
18
|
-
),
|
|
19
|
-
"data-align": (_a = column.align) != null ? _a : "left",
|
|
20
|
-
"data-divider": column.divider,
|
|
21
|
-
children: /* @__PURE__ */ jsx("div", { className: styles.cellContent, children: /* @__PURE__ */ jsx("div", { className: styles.cellValueEllipsis, children: /* @__PURE__ */ jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }) })
|
|
22
|
-
},
|
|
23
|
-
column.id
|
|
24
|
-
);
|
|
25
|
-
})
|
|
26
|
-
] }, `loading-row-${rowIndex}`)) });
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { TableLoadingBody };
|