@dbcdk/react-components 0.0.136 → 0.0.137
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/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.cjs +11 -9
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.js +11 -9
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.module.css +18 -14
- package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.module.css +12 -0
- package/dist/components/table/Table.cjs +3 -4
- package/dist/components/table/Table.d.ts +1 -1
- package/dist/components/table/Table.js +4 -5
- package/dist/components/table/Table.module.css +52 -21
- package/dist/components/table/Table.types.d.ts +9 -1
- package/dist/components/table/components/TableBody.cjs +2 -0
- package/dist/components/table/components/TableBody.d.ts +2 -1
- package/dist/components/table/components/TableBody.js +2 -0
- package/dist/components/table/components/TableHeader.cjs +1 -10
- package/dist/components/table/components/TableHeader.d.ts +1 -2
- package/dist/components/table/components/TableHeader.js +1 -10
- package/dist/components/table/components/TableRow.cjs +89 -68
- package/dist/components/table/components/TableRow.d.ts +2 -1
- package/dist/components/table/components/TableRow.js +89 -68
- package/dist/components/table/table.utils.cjs +0 -2
- package/dist/components/table/table.utils.d.ts +0 -1
- package/dist/components/table/table.utils.js +1 -2
- package/dist/components/table/tanstackTable.utils.cjs +2 -2
- package/dist/components/table/tanstackTable.utils.js +3 -3
- package/dist/hooks/useSorting.cjs +1 -0
- package/dist/hooks/useSorting.d.ts +6 -5
- package/dist/hooks/useSorting.js +1 -1
- package/dist/hooks/useTableData.cjs +29 -7
- package/dist/hooks/useTableData.d.ts +3 -1
- package/dist/hooks/useTableData.js +31 -9
- package/package.json +1 -1
package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.cjs
CHANGED
|
@@ -106,7 +106,7 @@ function ExpandableSidebarItem({
|
|
|
106
106
|
);
|
|
107
107
|
};
|
|
108
108
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.container}`, children: [
|
|
109
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.itemRow
|
|
109
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${styles__default.default.itemRow} ${expanded ? styles__default.default.itemRowExpanded : ""}`, children: [
|
|
110
110
|
/* @__PURE__ */ jsxRuntime.jsx(Component, { onClick: () => toggleAccordion(void 0, true), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
111
111
|
SidebarItemContent.SidebarItemContent,
|
|
112
112
|
{
|
|
@@ -116,23 +116,25 @@ function ExpandableSidebarItem({
|
|
|
116
116
|
label,
|
|
117
117
|
href,
|
|
118
118
|
disableActiveStyles: expanded,
|
|
119
|
+
suffixIcon: !isSidebarCollapsed ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
120
|
+
lucideReact.ChevronDown,
|
|
121
|
+
{
|
|
122
|
+
className: `${styles__default.default.chevron} ${expanded ? styles__default.default.chevronExpanded : ""}`
|
|
123
|
+
}
|
|
124
|
+
) : void 0,
|
|
119
125
|
truncateLabel
|
|
120
126
|
}
|
|
121
127
|
) }),
|
|
122
128
|
!isSidebarCollapsed && /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.toggleButton, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
123
129
|
Button.Button,
|
|
124
130
|
{
|
|
125
|
-
variant: "
|
|
131
|
+
variant: "inline",
|
|
132
|
+
shape: "round",
|
|
133
|
+
className: styles__default.default.toggleButtonControl,
|
|
126
134
|
"aria-label": expanded ? `Collapse ${label}` : `Expand ${label}`,
|
|
127
135
|
"aria-expanded": expanded,
|
|
128
136
|
"aria-controls": `${href}-children`,
|
|
129
|
-
onClick: toggleAccordion
|
|
130
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
131
|
-
lucideReact.ChevronDown,
|
|
132
|
-
{
|
|
133
|
-
className: `${styles__default.default.chevron} ${expanded ? styles__default.default.chevronExpanded : ""}`
|
|
134
|
-
}
|
|
135
|
-
)
|
|
137
|
+
onClick: toggleAccordion
|
|
136
138
|
}
|
|
137
139
|
) })
|
|
138
140
|
] }),
|
|
@@ -100,7 +100,7 @@ function ExpandableSidebarItem({
|
|
|
100
100
|
);
|
|
101
101
|
};
|
|
102
102
|
return /* @__PURE__ */ jsxs("div", { className: `${styles.container}`, children: [
|
|
103
|
-
/* @__PURE__ */ jsxs("div", { className: styles.itemRow
|
|
103
|
+
/* @__PURE__ */ jsxs("div", { className: `${styles.itemRow} ${expanded ? styles.itemRowExpanded : ""}`, children: [
|
|
104
104
|
/* @__PURE__ */ jsx(Component, { onClick: () => toggleAccordion(void 0, true), children: /* @__PURE__ */ jsx(
|
|
105
105
|
SidebarItemContent,
|
|
106
106
|
{
|
|
@@ -110,23 +110,25 @@ function ExpandableSidebarItem({
|
|
|
110
110
|
label,
|
|
111
111
|
href,
|
|
112
112
|
disableActiveStyles: expanded,
|
|
113
|
+
suffixIcon: !isSidebarCollapsed ? /* @__PURE__ */ jsx(
|
|
114
|
+
ChevronDown,
|
|
115
|
+
{
|
|
116
|
+
className: `${styles.chevron} ${expanded ? styles.chevronExpanded : ""}`
|
|
117
|
+
}
|
|
118
|
+
) : void 0,
|
|
113
119
|
truncateLabel
|
|
114
120
|
}
|
|
115
121
|
) }),
|
|
116
122
|
!isSidebarCollapsed && /* @__PURE__ */ jsx("div", { className: styles.toggleButton, children: /* @__PURE__ */ jsx(
|
|
117
123
|
Button,
|
|
118
124
|
{
|
|
119
|
-
variant: "
|
|
125
|
+
variant: "inline",
|
|
126
|
+
shape: "round",
|
|
127
|
+
className: styles.toggleButtonControl,
|
|
120
128
|
"aria-label": expanded ? `Collapse ${label}` : `Expand ${label}`,
|
|
121
129
|
"aria-expanded": expanded,
|
|
122
130
|
"aria-controls": `${href}-children`,
|
|
123
|
-
onClick: toggleAccordion
|
|
124
|
-
children: /* @__PURE__ */ jsx(
|
|
125
|
-
ChevronDown,
|
|
126
|
-
{
|
|
127
|
-
className: `${styles.chevron} ${expanded ? styles.chevronExpanded : ""}`
|
|
128
|
-
}
|
|
129
|
-
)
|
|
131
|
+
onClick: toggleAccordion
|
|
130
132
|
}
|
|
131
133
|
) })
|
|
132
134
|
] }),
|
package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.module.css
CHANGED
|
@@ -6,28 +6,32 @@
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
.itemRow {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
column-gap: var(--spacing-xs);
|
|
9
|
+
position: relative;
|
|
10
|
+
display: block;
|
|
11
|
+
border-radius: var(--border-radius-md);
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
.toggleButton {
|
|
16
|
-
|
|
15
|
+
position: absolute;
|
|
16
|
+
inset-inline-end: var(--spacing-xs);
|
|
17
|
+
inset-block-start: 50%;
|
|
18
|
+
transform: translateY(-50%);
|
|
19
|
+
display: inline-flex;
|
|
17
20
|
align-items: center;
|
|
18
21
|
justify-content: center;
|
|
19
|
-
flex: 0 0 auto;
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
.container button {
|
|
23
|
-
|
|
24
|
-
min-
|
|
25
|
-
|
|
26
|
-
max-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
min-block-size: 28px !important;
|
|
26
|
+
min-inline-size: 28px !important;
|
|
27
|
+
max-block-size: 28px !important;
|
|
28
|
+
max-inline-size: 28px !important;
|
|
29
|
+
border-color: transparent !important;
|
|
30
|
+
background-color: transparent !important;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.toggleButtonControl {
|
|
34
|
+
opacity: 0;
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
.childrenContainer {
|
package/dist/components/sidebar/components/sidebar-item-content/SidebarItemContent.module.css
CHANGED
|
@@ -53,6 +53,18 @@
|
|
|
53
53
|
color: var(--color-fg-default);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
.container:not(.active):hover .icon,
|
|
57
|
+
.container:not(.active):hover .suffixIcon,
|
|
58
|
+
.container:focus-visible .icon,
|
|
59
|
+
.container:focus-visible .suffixIcon {
|
|
60
|
+
color: var(--color-fg-default);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.active .icon,
|
|
64
|
+
.active .suffixIcon {
|
|
65
|
+
color: var(--color-fg-default);
|
|
66
|
+
}
|
|
67
|
+
|
|
56
68
|
.icon,
|
|
57
69
|
.suffixIcon {
|
|
58
70
|
inline-size: var(--sidebar-item-icon-width, auto);
|
|
@@ -52,6 +52,7 @@ function Table({
|
|
|
52
52
|
showHeader = true,
|
|
53
53
|
getRowSeverity,
|
|
54
54
|
getContextMenuItems,
|
|
55
|
+
showContextMenuOnHover = true,
|
|
55
56
|
onRowClick,
|
|
56
57
|
onRowMouseEnter,
|
|
57
58
|
onRowSelect,
|
|
@@ -65,7 +66,6 @@ function Table({
|
|
|
65
66
|
const internalTableRootRef = react.useRef(null);
|
|
66
67
|
const tableRootRefWrapper = react.useRef(tableRootRef);
|
|
67
68
|
const hasSelection = Boolean(selectedRows && onRowSelect);
|
|
68
|
-
const hasContextMenu = Boolean(getContextMenuItems);
|
|
69
69
|
const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
|
|
70
70
|
const paginationOffset = hasPagination ? 72 : 0;
|
|
71
71
|
const { style: viewportFillStyle, maxHeight } = useViewportFill.useViewportFill(internalTableRootRef, {
|
|
@@ -102,6 +102,7 @@ function Table({
|
|
|
102
102
|
viewMode,
|
|
103
103
|
getRowSeverity,
|
|
104
104
|
getContextMenuItems,
|
|
105
|
+
showContextMenuOnHover,
|
|
105
106
|
onRowClick,
|
|
106
107
|
onRowMouseEnter,
|
|
107
108
|
onRowSelect
|
|
@@ -158,15 +159,13 @@ function Table({
|
|
|
158
159
|
style: column.width != null ? { width: column.width } : void 0
|
|
159
160
|
},
|
|
160
161
|
column.id
|
|
161
|
-
))
|
|
162
|
-
hasContextMenu ? /* @__PURE__ */ jsxRuntime.jsx("col", { style: { width: table_utils.CONTEXT_MENU_COLUMN_PX } }) : null
|
|
162
|
+
))
|
|
163
163
|
] }),
|
|
164
164
|
showHeader && /* @__PURE__ */ jsxRuntime.jsx(
|
|
165
165
|
TableHeader.TableHeader,
|
|
166
166
|
{
|
|
167
167
|
columns: visibleColumns,
|
|
168
168
|
hasSelection,
|
|
169
|
-
hasContextMenu,
|
|
170
169
|
selectionMode,
|
|
171
170
|
allRowsSelected,
|
|
172
171
|
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, getContextMenuItems, 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, showContextMenuOnHover, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
|
|
4
4
|
export type { ColumnItem } from './Table.types';
|
|
@@ -9,7 +9,7 @@ import { TableBody } from './components/TableBody';
|
|
|
9
9
|
import { TableHeader } from './components/TableHeader';
|
|
10
10
|
import { cx } from './table.classes';
|
|
11
11
|
import styles from './Table.module.css';
|
|
12
|
-
import { getVisibleColumns, SELECTION_COLUMN_PX
|
|
12
|
+
import { getVisibleColumns, SELECTION_COLUMN_PX } from './table.utils';
|
|
13
13
|
|
|
14
14
|
function Table({
|
|
15
15
|
data,
|
|
@@ -46,6 +46,7 @@ function Table({
|
|
|
46
46
|
showHeader = true,
|
|
47
47
|
getRowSeverity,
|
|
48
48
|
getContextMenuItems,
|
|
49
|
+
showContextMenuOnHover = true,
|
|
49
50
|
onRowClick,
|
|
50
51
|
onRowMouseEnter,
|
|
51
52
|
onRowSelect,
|
|
@@ -59,7 +60,6 @@ function Table({
|
|
|
59
60
|
const internalTableRootRef = useRef(null);
|
|
60
61
|
const tableRootRefWrapper = useRef(tableRootRef);
|
|
61
62
|
const hasSelection = Boolean(selectedRows && onRowSelect);
|
|
62
|
-
const hasContextMenu = Boolean(getContextMenuItems);
|
|
63
63
|
const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
|
|
64
64
|
const paginationOffset = hasPagination ? 72 : 0;
|
|
65
65
|
const { style: viewportFillStyle, maxHeight } = useViewportFill(internalTableRootRef, {
|
|
@@ -96,6 +96,7 @@ function Table({
|
|
|
96
96
|
viewMode,
|
|
97
97
|
getRowSeverity,
|
|
98
98
|
getContextMenuItems,
|
|
99
|
+
showContextMenuOnHover,
|
|
99
100
|
onRowClick,
|
|
100
101
|
onRowMouseEnter,
|
|
101
102
|
onRowSelect
|
|
@@ -152,15 +153,13 @@ function Table({
|
|
|
152
153
|
style: column.width != null ? { width: column.width } : void 0
|
|
153
154
|
},
|
|
154
155
|
column.id
|
|
155
|
-
))
|
|
156
|
-
hasContextMenu ? /* @__PURE__ */ jsx("col", { style: { width: CONTEXT_MENU_COLUMN_PX } }) : null
|
|
156
|
+
))
|
|
157
157
|
] }),
|
|
158
158
|
showHeader && /* @__PURE__ */ jsx(
|
|
159
159
|
TableHeader,
|
|
160
160
|
{
|
|
161
161
|
columns: visibleColumns,
|
|
162
162
|
hasSelection,
|
|
163
|
-
hasContextMenu,
|
|
164
163
|
selectionMode,
|
|
165
164
|
allRowsSelected,
|
|
166
165
|
onSelectAllRows,
|
|
@@ -241,14 +241,6 @@
|
|
|
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
|
-
|
|
252
244
|
.headerCell.selectionCell {
|
|
253
245
|
padding-block: var(--spacing-xxs);
|
|
254
246
|
vertical-align: middle;
|
|
@@ -259,19 +251,10 @@
|
|
|
259
251
|
padding-block: var(--spacing-xxs);
|
|
260
252
|
}
|
|
261
253
|
|
|
262
|
-
.headerCell.contextMenuHeaderCell {
|
|
263
|
-
padding-block: var(--spacing-xxs);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
254
|
.headerCell:hover [data-resizer='true']::after {
|
|
267
255
|
opacity: 1;
|
|
268
256
|
}
|
|
269
257
|
|
|
270
|
-
.cell.contextMenuCell {
|
|
271
|
-
vertical-align: top;
|
|
272
|
-
padding-block: var(--spacing-2xs);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
258
|
.selectionHitArea {
|
|
276
259
|
display: inline-flex;
|
|
277
260
|
align-items: flex-start;
|
|
@@ -496,10 +479,6 @@
|
|
|
496
479
|
text-align: right;
|
|
497
480
|
}
|
|
498
481
|
|
|
499
|
-
.contextMenuCellContent {
|
|
500
|
-
justify-content: flex-end;
|
|
501
|
-
}
|
|
502
|
-
|
|
503
482
|
/* vertical alignment inside content wrapper */
|
|
504
483
|
.cellContent[data-vertical-align='top'] {
|
|
505
484
|
align-items: flex-start;
|
|
@@ -562,6 +541,58 @@
|
|
|
562
541
|
|
|
563
542
|
.contextMenuTrigger {
|
|
564
543
|
color: var(--color-fg-subtle);
|
|
544
|
+
min-inline-size: 36px;
|
|
545
|
+
min-block-size: 36px;
|
|
546
|
+
border-radius: var(--border-radius-rounded);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.contextMenuAnchorCell {
|
|
550
|
+
overflow: visible;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
.contextMenuAnchorCell .cellValueEllipsis,
|
|
554
|
+
.contextMenuAnchorCell .cellValueNoEllipsis {
|
|
555
|
+
padding-inline-end: calc(36px + var(--spacing-sm));
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
.contextMenuOverlay {
|
|
559
|
+
position: absolute;
|
|
560
|
+
inset-block-start: 50%;
|
|
561
|
+
inset-inline-end: 0;
|
|
562
|
+
transform: translateY(-50%);
|
|
563
|
+
display: inline-flex;
|
|
564
|
+
align-items: center;
|
|
565
|
+
justify-content: center;
|
|
566
|
+
min-inline-size: 40px;
|
|
567
|
+
min-block-size: 40px;
|
|
568
|
+
z-index: 3;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
.contextMenuOverlay:hover .contextMenuTrigger,
|
|
572
|
+
.contextMenuOverlay:focus-within .contextMenuTrigger {
|
|
573
|
+
background-color: var(--opac-bg-light);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
.contextMenuItemLabel {
|
|
577
|
+
display: inline-flex;
|
|
578
|
+
align-items: flex-start;
|
|
579
|
+
gap: var(--spacing-xs);
|
|
580
|
+
min-width: 0;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.contextMenuItemText {
|
|
584
|
+
min-width: 0;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.contextMenuHoverOnly .contextMenuTrigger {
|
|
588
|
+
opacity: 0;
|
|
589
|
+
pointer-events: none;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.contextMenuHoverOnly:hover .contextMenuTrigger,
|
|
593
|
+
.contextMenuHoverOnly:focus-within .contextMenuTrigger {
|
|
594
|
+
opacity: 1;
|
|
595
|
+
pointer-events: auto;
|
|
565
596
|
}
|
|
566
597
|
|
|
567
598
|
.severityTable {
|
|
@@ -24,14 +24,21 @@ export type HeaderExtrasArgs<T> = {
|
|
|
24
24
|
column: ColumnItem<T>;
|
|
25
25
|
index: number;
|
|
26
26
|
};
|
|
27
|
-
export type
|
|
27
|
+
export type TableContextMenuActionItem = {
|
|
28
|
+
type?: 'item';
|
|
28
29
|
label: ReactNode;
|
|
30
|
+
icon?: ReactNode;
|
|
29
31
|
onClick: () => void;
|
|
30
32
|
active?: boolean;
|
|
31
33
|
selected?: boolean;
|
|
32
34
|
disabled?: boolean;
|
|
33
35
|
variant?: 'default' | 'danger';
|
|
34
36
|
};
|
|
37
|
+
export type TableContextMenuHeaderItem = {
|
|
38
|
+
type: 'header';
|
|
39
|
+
label: ReactNode;
|
|
40
|
+
};
|
|
41
|
+
export type TableContextMenuItem = TableContextMenuActionItem | TableContextMenuHeaderItem;
|
|
35
42
|
export type StickyHeader = false | 'app-header' | number;
|
|
36
43
|
export type TableVariant = 'primary' | 'embedded';
|
|
37
44
|
export type SortDirection = 'asc' | 'desc' | null;
|
|
@@ -74,6 +81,7 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
|
|
|
74
81
|
rowId: string | number;
|
|
75
82
|
open: () => void;
|
|
76
83
|
}) => TableContextMenuItem[];
|
|
84
|
+
showContextMenuOnHover?: boolean;
|
|
77
85
|
onRowClick?: (row: T) => void;
|
|
78
86
|
onRowMouseEnter?: (row: T) => void;
|
|
79
87
|
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
@@ -21,6 +21,7 @@ function TableBody({
|
|
|
21
21
|
viewMode,
|
|
22
22
|
getRowSeverity,
|
|
23
23
|
getContextMenuItems,
|
|
24
|
+
showContextMenuOnHover,
|
|
24
25
|
onRowClick,
|
|
25
26
|
onRowMouseEnter,
|
|
26
27
|
onRowSelect
|
|
@@ -40,6 +41,7 @@ function TableBody({
|
|
|
40
41
|
viewMode,
|
|
41
42
|
getRowSeverity,
|
|
42
43
|
getContextMenuItems,
|
|
44
|
+
showContextMenuOnHover,
|
|
43
45
|
onRowClick,
|
|
44
46
|
onRowMouseEnter,
|
|
45
47
|
onRowSelect
|
|
@@ -17,9 +17,10 @@ type Props<T extends Record<string, any>> = {
|
|
|
17
17
|
rowId: string | number;
|
|
18
18
|
open: () => void;
|
|
19
19
|
}) => TableContextMenuItem[];
|
|
20
|
+
showContextMenuOnHover: boolean;
|
|
20
21
|
onRowClick?: (row: T) => void;
|
|
21
22
|
onRowMouseEnter?: (row: T) => void;
|
|
22
23
|
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
23
24
|
};
|
|
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;
|
|
25
|
+
export declare function TableBody<T extends Record<string, any>>({ data, dataKey, columns, striped, selectedRows, hasSelection, selectionMode, selectionInputName, viewMode, getRowSeverity, getContextMenuItems, showContextMenuOnHover, onRowClick, onRowMouseEnter, onRowSelect, }: Props<T>): ReactNode;
|
|
25
26
|
export {};
|
|
@@ -15,6 +15,7 @@ function TableBody({
|
|
|
15
15
|
viewMode,
|
|
16
16
|
getRowSeverity,
|
|
17
17
|
getContextMenuItems,
|
|
18
|
+
showContextMenuOnHover,
|
|
18
19
|
onRowClick,
|
|
19
20
|
onRowMouseEnter,
|
|
20
21
|
onRowSelect
|
|
@@ -34,6 +35,7 @@ function TableBody({
|
|
|
34
35
|
viewMode,
|
|
35
36
|
getRowSeverity,
|
|
36
37
|
getContextMenuItems,
|
|
38
|
+
showContextMenuOnHover,
|
|
37
39
|
onRowClick,
|
|
38
40
|
onRowMouseEnter,
|
|
39
41
|
onRowSelect
|
|
@@ -12,7 +12,6 @@ var styles__default = /*#__PURE__*/_interopDefault(styles);
|
|
|
12
12
|
function TableHeader({
|
|
13
13
|
columns,
|
|
14
14
|
hasSelection,
|
|
15
|
-
hasContextMenu,
|
|
16
15
|
selectionMode,
|
|
17
16
|
allRowsSelected,
|
|
18
17
|
onSelectAllRows,
|
|
@@ -48,15 +47,7 @@ function TableHeader({
|
|
|
48
47
|
extraContent: headerExtras == null ? void 0 : headerExtras({ column, index })
|
|
49
48
|
},
|
|
50
49
|
column.id
|
|
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
|
|
50
|
+
))
|
|
60
51
|
] })
|
|
61
52
|
}
|
|
62
53
|
);
|
|
@@ -3,7 +3,6 @@ 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;
|
|
7
6
|
selectionMode: 'single' | 'multiple';
|
|
8
7
|
allRowsSelected?: boolean;
|
|
9
8
|
onSelectAllRows?: (isSelected: boolean) => void;
|
|
@@ -13,5 +12,5 @@ type Props<T> = {
|
|
|
13
12
|
headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
|
|
14
13
|
stickyTop?: string;
|
|
15
14
|
};
|
|
16
|
-
export declare function TableHeader<T>({ columns, hasSelection,
|
|
15
|
+
export declare function TableHeader<T>({ columns, hasSelection, selectionMode, allRowsSelected, onSelectAllRows, sortById, sortDirection, onSortChange, headerExtras, stickyTop, }: Props<T>): React.ReactNode;
|
|
17
16
|
export {};
|
|
@@ -6,7 +6,6 @@ import styles from '../Table.module.css';
|
|
|
6
6
|
function TableHeader({
|
|
7
7
|
columns,
|
|
8
8
|
hasSelection,
|
|
9
|
-
hasContextMenu,
|
|
10
9
|
selectionMode,
|
|
11
10
|
allRowsSelected,
|
|
12
11
|
onSelectAllRows,
|
|
@@ -42,15 +41,7 @@ function TableHeader({
|
|
|
42
41
|
extraContent: headerExtras == null ? void 0 : headerExtras({ column, index })
|
|
43
42
|
},
|
|
44
43
|
column.id
|
|
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
|
|
44
|
+
))
|
|
54
45
|
] })
|
|
55
46
|
}
|
|
56
47
|
);
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var lucideReact = require('lucide-react');
|
|
5
|
+
var react = require('react');
|
|
5
6
|
var Checkbox = require('../../../components/forms/checkbox/Checkbox');
|
|
6
7
|
var RadioButton = require('../../../components/forms/radio-buttons/RadioButton');
|
|
7
8
|
var Popover = require('../../../components/popover/Popover');
|
|
@@ -28,6 +29,7 @@ function TableRow({
|
|
|
28
29
|
viewMode,
|
|
29
30
|
getRowSeverity,
|
|
30
31
|
getContextMenuItems,
|
|
32
|
+
showContextMenuOnHover,
|
|
31
33
|
onRowClick,
|
|
32
34
|
onRowMouseEnter,
|
|
33
35
|
onRowSelect
|
|
@@ -41,6 +43,7 @@ function TableRow({
|
|
|
41
43
|
rowId,
|
|
42
44
|
open: () => onRowClick == null ? void 0 : onRowClick(row)
|
|
43
45
|
});
|
|
46
|
+
const hasContextMenu = Boolean(contextMenuItems == null ? void 0 : contextMenuItems.length);
|
|
44
47
|
const { handleRowClick, handleRowKeyDown } = useTableRowInteractions.useTableRowInteractions({
|
|
45
48
|
row,
|
|
46
49
|
rowId,
|
|
@@ -56,8 +59,10 @@ function TableRow({
|
|
|
56
59
|
styles__default.default.row,
|
|
57
60
|
onRowClick && styles__default.default.clickableRow,
|
|
58
61
|
isSelected && styles__default.default.selectedRow,
|
|
59
|
-
rowSeverity && styles__default.default.severity
|
|
62
|
+
rowSeverity && styles__default.default.severity,
|
|
63
|
+
hasContextMenu && showContextMenuOnHover && styles__default.default.contextMenuHoverOnly
|
|
60
64
|
),
|
|
65
|
+
"data-context-menu-visibility": hasContextMenu ? showContextMenuOnHover ? "hover" : "always" : void 0,
|
|
61
66
|
style: {
|
|
62
67
|
["--row-severity-color"]: rowSeverity ? `color-mix(in srgb, ${severity.SeverityBgColor[rowSeverity]} 65%, var(--table-component-row-bg))` : void 0
|
|
63
68
|
},
|
|
@@ -124,10 +129,11 @@ function TableRow({
|
|
|
124
129
|
}
|
|
125
130
|
) }) : null,
|
|
126
131
|
columns.map((column) => {
|
|
127
|
-
var _a2, _b, _c, _d;
|
|
132
|
+
var _a2, _b, _c, _d, _e;
|
|
128
133
|
const allowWrap = table_utils.shouldAllowWrap(column.allowWrap, isSelected, viewMode);
|
|
129
134
|
const allowOverflow = column.allowOverflow;
|
|
130
135
|
const cellValue = table_utils.getCellDisplayValue(row, column);
|
|
136
|
+
const isLastColumn = column.id === ((_a2 = columns[columns.length - 1]) == null ? void 0 : _a2.id);
|
|
131
137
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
132
138
|
"td",
|
|
133
139
|
{
|
|
@@ -135,96 +141,111 @@ function TableRow({
|
|
|
135
141
|
styles__default.default.cell,
|
|
136
142
|
allowOverflow && styles__default.default.allowOverflow,
|
|
137
143
|
allowWrap ? styles__default.default.allowWrap : styles__default.default.nowrap,
|
|
144
|
+
hasContextMenu && isLastColumn && styles__default.default.contextMenuAnchorCell,
|
|
138
145
|
column.divider === "left" && styles__default.default.dividerLeft,
|
|
139
146
|
column.divider === "right" && styles__default.default.dividerRight
|
|
140
147
|
),
|
|
141
|
-
"data-align": (
|
|
142
|
-
"data-vertical-align": (
|
|
148
|
+
"data-align": (_b = column.align) != null ? _b : "left",
|
|
149
|
+
"data-vertical-align": (_c = column.verticalAlign) != null ? _c : "top",
|
|
143
150
|
"data-divider": column.divider,
|
|
144
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
151
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
145
152
|
"div",
|
|
146
153
|
{
|
|
147
154
|
className: styles__default.default.cellContent,
|
|
148
|
-
"data-align": (
|
|
149
|
-
"data-vertical-align": (
|
|
150
|
-
children:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
"data-align": (_d = column.align) != null ? _d : "left",
|
|
156
|
+
"data-vertical-align": (_e = column.verticalAlign) != null ? _e : "top",
|
|
157
|
+
children: [
|
|
158
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
159
|
+
"div",
|
|
160
|
+
{
|
|
161
|
+
className: allowOverflow ? styles__default.default.cellValueNoEllipsis : styles__default.default.cellValueEllipsis,
|
|
162
|
+
children: cellValue
|
|
163
|
+
}
|
|
164
|
+
),
|
|
165
|
+
hasContextMenu && isLastColumn ? /* @__PURE__ */ jsxRuntime.jsx(RowContextMenu, { rowId, items: contextMenuItems }) : null
|
|
166
|
+
]
|
|
157
167
|
}
|
|
158
168
|
)
|
|
159
169
|
},
|
|
160
170
|
column.id
|
|
161
171
|
);
|
|
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
|
|
172
|
+
})
|
|
172
173
|
]
|
|
173
174
|
}
|
|
174
175
|
);
|
|
175
176
|
}
|
|
176
177
|
function RowContextMenu({
|
|
177
|
-
row,
|
|
178
178
|
rowId,
|
|
179
179
|
items
|
|
180
180
|
}) {
|
|
181
|
+
const toggleRef = react.useRef(null);
|
|
181
182
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
182
|
-
|
|
183
|
+
"div",
|
|
183
184
|
{
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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.MoreVertical, { 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,
|
|
185
|
+
className: styles__default.default.contextMenuOverlay,
|
|
186
|
+
"data-row-context-menu": "true",
|
|
187
|
+
onClick: (e) => {
|
|
188
|
+
var _a;
|
|
189
|
+
e.stopPropagation();
|
|
190
|
+
(_a = toggleRef.current) == null ? void 0 : _a.call(toggleRef, e);
|
|
191
|
+
},
|
|
192
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
193
|
+
Popover.Popover,
|
|
207
194
|
{
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
195
|
+
matchTriggerWidth: false,
|
|
196
|
+
minWidth: "180px",
|
|
197
|
+
trigger: (toggle, _icon, isOpen) => {
|
|
198
|
+
toggleRef.current = toggle;
|
|
199
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
200
|
+
Button.Button,
|
|
201
|
+
{
|
|
202
|
+
type: "button",
|
|
203
|
+
size: "sm",
|
|
204
|
+
variant: "inline",
|
|
205
|
+
shape: "round",
|
|
206
|
+
className: styles__default.default.contextMenuTrigger,
|
|
207
|
+
"aria-label": `Flere handlinger for r\xE6kke ${String(rowId)}`,
|
|
208
|
+
"aria-haspopup": "menu",
|
|
209
|
+
"aria-expanded": isOpen ? true : false,
|
|
210
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreVertical, { size: 16 }),
|
|
211
|
+
"data-row-context-menu": "true",
|
|
212
|
+
onClick: (e) => {
|
|
213
|
+
e.stopPropagation();
|
|
214
|
+
toggle(e);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
);
|
|
218
|
+
},
|
|
219
|
+
children: (close) => /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu, { children: items.map(
|
|
220
|
+
(item, index) => item.type === "header" ? /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Header, { children: item.label }, index) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
221
|
+
Menu.Menu.Item,
|
|
222
|
+
{
|
|
223
|
+
active: item.active,
|
|
224
|
+
selected: item.selected,
|
|
225
|
+
disabled: item.disabled,
|
|
226
|
+
variant: item.variant,
|
|
227
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
228
|
+
"button",
|
|
229
|
+
{
|
|
230
|
+
type: "button",
|
|
231
|
+
"data-row-context-menu": "true",
|
|
232
|
+
onClick: (e) => {
|
|
233
|
+
e.stopPropagation();
|
|
234
|
+
item.onClick();
|
|
235
|
+
close();
|
|
236
|
+
},
|
|
237
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.contextMenuItemLabel, children: [
|
|
238
|
+
item.icon,
|
|
239
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.contextMenuItemText, children: item.label })
|
|
240
|
+
] })
|
|
241
|
+
}
|
|
242
|
+
)
|
|
221
243
|
},
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
)
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
)) })
|
|
244
|
+
index
|
|
245
|
+
)
|
|
246
|
+
) })
|
|
247
|
+
}
|
|
248
|
+
)
|
|
228
249
|
}
|
|
229
250
|
);
|
|
230
251
|
}
|
|
@@ -16,9 +16,10 @@ type Props<T extends Record<string, any>> = {
|
|
|
16
16
|
rowId: string | number;
|
|
17
17
|
open: () => void;
|
|
18
18
|
}) => TableContextMenuItem[];
|
|
19
|
+
showContextMenuOnHover: boolean;
|
|
19
20
|
onRowClick?: (row: T) => void;
|
|
20
21
|
onRowMouseEnter?: (row: T) => void;
|
|
21
22
|
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
22
23
|
};
|
|
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;
|
|
24
|
+
export declare function TableRow<T extends Record<string, any>>({ row, rowId, columns, selectedRows, hasSelection, selectionMode, selectionInputName, viewMode, getRowSeverity, getContextMenuItems, showContextMenuOnHover, onRowClick, onRowMouseEnter, onRowSelect, }: Props<T>): React.ReactNode;
|
|
24
25
|
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { MoreVertical } from 'lucide-react';
|
|
3
|
+
import { useRef } from 'react';
|
|
3
4
|
import { Checkbox } from '../../../components/forms/checkbox/Checkbox';
|
|
4
5
|
import { RadioButton } from '../../../components/forms/radio-buttons/RadioButton';
|
|
5
6
|
import { Popover } from '../../../components/popover/Popover';
|
|
@@ -22,6 +23,7 @@ function TableRow({
|
|
|
22
23
|
viewMode,
|
|
23
24
|
getRowSeverity,
|
|
24
25
|
getContextMenuItems,
|
|
26
|
+
showContextMenuOnHover,
|
|
25
27
|
onRowClick,
|
|
26
28
|
onRowMouseEnter,
|
|
27
29
|
onRowSelect
|
|
@@ -35,6 +37,7 @@ function TableRow({
|
|
|
35
37
|
rowId,
|
|
36
38
|
open: () => onRowClick == null ? void 0 : onRowClick(row)
|
|
37
39
|
});
|
|
40
|
+
const hasContextMenu = Boolean(contextMenuItems == null ? void 0 : contextMenuItems.length);
|
|
38
41
|
const { handleRowClick, handleRowKeyDown } = useTableRowInteractions({
|
|
39
42
|
row,
|
|
40
43
|
rowId,
|
|
@@ -50,8 +53,10 @@ function TableRow({
|
|
|
50
53
|
styles.row,
|
|
51
54
|
onRowClick && styles.clickableRow,
|
|
52
55
|
isSelected && styles.selectedRow,
|
|
53
|
-
rowSeverity && styles.severity
|
|
56
|
+
rowSeverity && styles.severity,
|
|
57
|
+
hasContextMenu && showContextMenuOnHover && styles.contextMenuHoverOnly
|
|
54
58
|
),
|
|
59
|
+
"data-context-menu-visibility": hasContextMenu ? showContextMenuOnHover ? "hover" : "always" : void 0,
|
|
55
60
|
style: {
|
|
56
61
|
["--row-severity-color"]: rowSeverity ? `color-mix(in srgb, ${SeverityBgColor[rowSeverity]} 65%, var(--table-component-row-bg))` : void 0
|
|
57
62
|
},
|
|
@@ -118,10 +123,11 @@ function TableRow({
|
|
|
118
123
|
}
|
|
119
124
|
) }) : null,
|
|
120
125
|
columns.map((column) => {
|
|
121
|
-
var _a2, _b, _c, _d;
|
|
126
|
+
var _a2, _b, _c, _d, _e;
|
|
122
127
|
const allowWrap = shouldAllowWrap(column.allowWrap, isSelected, viewMode);
|
|
123
128
|
const allowOverflow = column.allowOverflow;
|
|
124
129
|
const cellValue = getCellDisplayValue(row, column);
|
|
130
|
+
const isLastColumn = column.id === ((_a2 = columns[columns.length - 1]) == null ? void 0 : _a2.id);
|
|
125
131
|
return /* @__PURE__ */ jsx(
|
|
126
132
|
"td",
|
|
127
133
|
{
|
|
@@ -129,96 +135,111 @@ function TableRow({
|
|
|
129
135
|
styles.cell,
|
|
130
136
|
allowOverflow && styles.allowOverflow,
|
|
131
137
|
allowWrap ? styles.allowWrap : styles.nowrap,
|
|
138
|
+
hasContextMenu && isLastColumn && styles.contextMenuAnchorCell,
|
|
132
139
|
column.divider === "left" && styles.dividerLeft,
|
|
133
140
|
column.divider === "right" && styles.dividerRight
|
|
134
141
|
),
|
|
135
|
-
"data-align": (
|
|
136
|
-
"data-vertical-align": (
|
|
142
|
+
"data-align": (_b = column.align) != null ? _b : "left",
|
|
143
|
+
"data-vertical-align": (_c = column.verticalAlign) != null ? _c : "top",
|
|
137
144
|
"data-divider": column.divider,
|
|
138
|
-
children: /* @__PURE__ */
|
|
145
|
+
children: /* @__PURE__ */ jsxs(
|
|
139
146
|
"div",
|
|
140
147
|
{
|
|
141
148
|
className: styles.cellContent,
|
|
142
|
-
"data-align": (
|
|
143
|
-
"data-vertical-align": (
|
|
144
|
-
children:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
"data-align": (_d = column.align) != null ? _d : "left",
|
|
150
|
+
"data-vertical-align": (_e = column.verticalAlign) != null ? _e : "top",
|
|
151
|
+
children: [
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
"div",
|
|
154
|
+
{
|
|
155
|
+
className: allowOverflow ? styles.cellValueNoEllipsis : styles.cellValueEllipsis,
|
|
156
|
+
children: cellValue
|
|
157
|
+
}
|
|
158
|
+
),
|
|
159
|
+
hasContextMenu && isLastColumn ? /* @__PURE__ */ jsx(RowContextMenu, { rowId, items: contextMenuItems }) : null
|
|
160
|
+
]
|
|
151
161
|
}
|
|
152
162
|
)
|
|
153
163
|
},
|
|
154
164
|
column.id
|
|
155
165
|
);
|
|
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
|
|
166
|
+
})
|
|
166
167
|
]
|
|
167
168
|
}
|
|
168
169
|
);
|
|
169
170
|
}
|
|
170
171
|
function RowContextMenu({
|
|
171
|
-
row,
|
|
172
172
|
rowId,
|
|
173
173
|
items
|
|
174
174
|
}) {
|
|
175
|
+
const toggleRef = useRef(null);
|
|
175
176
|
return /* @__PURE__ */ jsx(
|
|
176
|
-
|
|
177
|
+
"div",
|
|
177
178
|
{
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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(MoreVertical, { 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,
|
|
179
|
+
className: styles.contextMenuOverlay,
|
|
180
|
+
"data-row-context-menu": "true",
|
|
181
|
+
onClick: (e) => {
|
|
182
|
+
var _a;
|
|
183
|
+
e.stopPropagation();
|
|
184
|
+
(_a = toggleRef.current) == null ? void 0 : _a.call(toggleRef, e);
|
|
185
|
+
},
|
|
186
|
+
children: /* @__PURE__ */ jsx(
|
|
187
|
+
Popover,
|
|
201
188
|
{
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
189
|
+
matchTriggerWidth: false,
|
|
190
|
+
minWidth: "180px",
|
|
191
|
+
trigger: (toggle, _icon, isOpen) => {
|
|
192
|
+
toggleRef.current = toggle;
|
|
193
|
+
return /* @__PURE__ */ jsx(
|
|
194
|
+
Button,
|
|
195
|
+
{
|
|
196
|
+
type: "button",
|
|
197
|
+
size: "sm",
|
|
198
|
+
variant: "inline",
|
|
199
|
+
shape: "round",
|
|
200
|
+
className: styles.contextMenuTrigger,
|
|
201
|
+
"aria-label": `Flere handlinger for r\xE6kke ${String(rowId)}`,
|
|
202
|
+
"aria-haspopup": "menu",
|
|
203
|
+
"aria-expanded": isOpen ? true : false,
|
|
204
|
+
icon: /* @__PURE__ */ jsx(MoreVertical, { size: 16 }),
|
|
205
|
+
"data-row-context-menu": "true",
|
|
206
|
+
onClick: (e) => {
|
|
207
|
+
e.stopPropagation();
|
|
208
|
+
toggle(e);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
);
|
|
212
|
+
},
|
|
213
|
+
children: (close) => /* @__PURE__ */ jsx(Menu, { children: items.map(
|
|
214
|
+
(item, index) => item.type === "header" ? /* @__PURE__ */ jsx(Menu.Header, { children: item.label }, index) : /* @__PURE__ */ jsx(
|
|
215
|
+
Menu.Item,
|
|
216
|
+
{
|
|
217
|
+
active: item.active,
|
|
218
|
+
selected: item.selected,
|
|
219
|
+
disabled: item.disabled,
|
|
220
|
+
variant: item.variant,
|
|
221
|
+
children: /* @__PURE__ */ jsx(
|
|
222
|
+
"button",
|
|
223
|
+
{
|
|
224
|
+
type: "button",
|
|
225
|
+
"data-row-context-menu": "true",
|
|
226
|
+
onClick: (e) => {
|
|
227
|
+
e.stopPropagation();
|
|
228
|
+
item.onClick();
|
|
229
|
+
close();
|
|
230
|
+
},
|
|
231
|
+
children: /* @__PURE__ */ jsxs("span", { className: styles.contextMenuItemLabel, children: [
|
|
232
|
+
item.icon,
|
|
233
|
+
/* @__PURE__ */ jsx("span", { className: styles.contextMenuItemText, children: item.label })
|
|
234
|
+
] })
|
|
235
|
+
}
|
|
236
|
+
)
|
|
215
237
|
},
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
)) })
|
|
238
|
+
index
|
|
239
|
+
)
|
|
240
|
+
) })
|
|
241
|
+
}
|
|
242
|
+
)
|
|
222
243
|
}
|
|
223
244
|
);
|
|
224
245
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const SELECTION_COLUMN_PX = 40;
|
|
4
|
-
const CONTEXT_MENU_COLUMN_PX = 44;
|
|
5
4
|
const DEFAULT_COLUMN_PX = 150;
|
|
6
5
|
function getVisibleColumns(columns) {
|
|
7
6
|
return columns.filter((column) => !column.hidden);
|
|
@@ -45,7 +44,6 @@ function getCellDisplayValue(row, column) {
|
|
|
45
44
|
return empty;
|
|
46
45
|
}
|
|
47
46
|
|
|
48
|
-
exports.CONTEXT_MENU_COLUMN_PX = CONTEXT_MENU_COLUMN_PX;
|
|
49
47
|
exports.DEFAULT_COLUMN_PX = DEFAULT_COLUMN_PX;
|
|
50
48
|
exports.SELECTION_COLUMN_PX = SELECTION_COLUMN_PX;
|
|
51
49
|
exports.getAriaSort = getAriaSort;
|
|
@@ -1,7 +1,6 @@
|
|
|
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;
|
|
5
4
|
export declare const DEFAULT_COLUMN_PX: 150;
|
|
6
5
|
export type SortDirection = 'asc' | 'desc' | null;
|
|
7
6
|
export declare function getVisibleColumns<T>(columns: Array<ColumnItem<T>>): Array<ColumnItem<T>>;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const SELECTION_COLUMN_PX = 40;
|
|
2
|
-
const CONTEXT_MENU_COLUMN_PX = 44;
|
|
3
2
|
const DEFAULT_COLUMN_PX = 150;
|
|
4
3
|
function getVisibleColumns(columns) {
|
|
5
4
|
return columns.filter((column) => !column.hidden);
|
|
@@ -43,4 +42,4 @@ function getCellDisplayValue(row, column) {
|
|
|
43
42
|
return empty;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
export {
|
|
45
|
+
export { DEFAULT_COLUMN_PX, SELECTION_COLUMN_PX, getAriaSort, getCellDisplayValue, getHeaderLabel, getNextSortDirection, getVisibleColumns, isActiveSort, isModifierClick, shouldAllowWrap, shouldToggleOnKey };
|
|
@@ -103,7 +103,7 @@ function buildDistributedColumnWidths(args) {
|
|
|
103
103
|
} = args;
|
|
104
104
|
const leaf = table.getVisibleLeafColumns();
|
|
105
105
|
const selectionWidth = hasSelection ? table_utils.SELECTION_COLUMN_PX : 0;
|
|
106
|
-
const contextMenuWidth = hasContextMenu ?
|
|
106
|
+
const contextMenuWidth = hasContextMenu ? 0 : 0;
|
|
107
107
|
const tracks = leaf.map((c) => {
|
|
108
108
|
var _a, _b, _c, _d;
|
|
109
109
|
const def = c.columnDef;
|
|
@@ -165,7 +165,7 @@ function buildDistributedColumnWidths(args) {
|
|
|
165
165
|
const totalWidth = selectionWidth + contextMenuWidth + Object.values(widths).reduce((sum, width) => sum + width, 0);
|
|
166
166
|
return {
|
|
167
167
|
selectionWidth: hasSelection ? table_utils.SELECTION_COLUMN_PX : void 0,
|
|
168
|
-
contextMenuWidth: hasContextMenu ?
|
|
168
|
+
contextMenuWidth: hasContextMenu ? 0 : void 0,
|
|
169
169
|
widths,
|
|
170
170
|
totalWidth,
|
|
171
171
|
availableWidth,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_COLUMN_PX,
|
|
1
|
+
import { DEFAULT_COLUMN_PX, SELECTION_COLUMN_PX } from './table.utils';
|
|
2
2
|
|
|
3
3
|
function getColumnId(def, index) {
|
|
4
4
|
const d = def;
|
|
@@ -101,7 +101,7 @@ function buildDistributedColumnWidths(args) {
|
|
|
101
101
|
} = args;
|
|
102
102
|
const leaf = table.getVisibleLeafColumns();
|
|
103
103
|
const selectionWidth = hasSelection ? SELECTION_COLUMN_PX : 0;
|
|
104
|
-
const contextMenuWidth = hasContextMenu ?
|
|
104
|
+
const contextMenuWidth = hasContextMenu ? 0 : 0;
|
|
105
105
|
const tracks = leaf.map((c) => {
|
|
106
106
|
var _a, _b, _c, _d;
|
|
107
107
|
const def = c.columnDef;
|
|
@@ -163,7 +163,7 @@ function buildDistributedColumnWidths(args) {
|
|
|
163
163
|
const totalWidth = selectionWidth + contextMenuWidth + Object.values(widths).reduce((sum, width) => sum + width, 0);
|
|
164
164
|
return {
|
|
165
165
|
selectionWidth: hasSelection ? SELECTION_COLUMN_PX : void 0,
|
|
166
|
-
contextMenuWidth: hasContextMenu ?
|
|
166
|
+
contextMenuWidth: hasContextMenu ? 0 : void 0,
|
|
167
167
|
widths,
|
|
168
168
|
totalWidth,
|
|
169
169
|
availableWidth,
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
export type SortDirection = 'asc' | 'desc' | null;
|
|
2
|
-
export type SortState<T> = {
|
|
3
|
-
sortBy:
|
|
2
|
+
export type SortState<T = unknown> = {
|
|
3
|
+
sortBy: string | null;
|
|
4
4
|
sortDirection: SortDirection;
|
|
5
5
|
};
|
|
6
|
-
export type SortEvent<T> = Partial<SortState<T>>;
|
|
7
|
-
export type ColumnComparators<T> = Partial<Record<
|
|
6
|
+
export type SortEvent<T = unknown> = Partial<SortState<T>>;
|
|
7
|
+
export type ColumnComparators<T> = Partial<Record<string, (a: T, b: T, direction: Exclude<SortDirection, null>) => number>>;
|
|
8
8
|
export interface UseSortingProps<T> {
|
|
9
9
|
data?: readonly T[];
|
|
10
10
|
/**
|
|
11
11
|
* Default/initial state. If you pass `state`, these are ignored.
|
|
12
12
|
*/
|
|
13
|
-
sortBy?:
|
|
13
|
+
sortBy?: string | null;
|
|
14
14
|
sortDirection?: SortDirection;
|
|
15
15
|
/**
|
|
16
16
|
* Controlled mode: if provided, hook will not keep its own state.
|
|
@@ -46,4 +46,5 @@ export interface UseSortingResult<T> {
|
|
|
46
46
|
setSort: (next: SortState<T>) => void;
|
|
47
47
|
clearSort: () => void;
|
|
48
48
|
}
|
|
49
|
+
export declare function defaultCompare(a: unknown, b: unknown, dir: 'asc' | 'desc', nulls: 'first' | 'last'): number;
|
|
49
50
|
export declare function useSorting<T extends Record<string, any>>({ data, sortBy, sortDirection, state, onStateChange, columnComparators, nulls, allowUnsort, resetOnDataChange, }: UseSortingProps<T>): UseSortingResult<T>;
|
package/dist/hooks/useSorting.js
CHANGED
|
@@ -12,28 +12,50 @@ function useTableData({
|
|
|
12
12
|
resetPageOnSortChange = true
|
|
13
13
|
}) {
|
|
14
14
|
var _a, _b, _c, _d, _e, _f;
|
|
15
|
+
const hasPagination = pagination != null;
|
|
16
|
+
const nullsMode = (_a = sorting == null ? void 0 : sorting.nulls) != null ? _a : "last";
|
|
17
|
+
const mergedComparators = react.useMemo(() => {
|
|
18
|
+
var _a2, _b2;
|
|
19
|
+
const derived = {};
|
|
20
|
+
for (const col of (_a2 = sorting == null ? void 0 : sorting.columns) != null ? _a2 : []) {
|
|
21
|
+
const colId = (_b2 = col.id) != null ? _b2 : col.accessorKey;
|
|
22
|
+
if (!colId) continue;
|
|
23
|
+
const accessorFn = col.accessorFn;
|
|
24
|
+
const accessorKey = col.accessorKey;
|
|
25
|
+
if (accessorFn) {
|
|
26
|
+
derived[colId] = (a, b, dir) => useSorting.defaultCompare(accessorFn(a, 0), accessorFn(b, 0), dir, nullsMode);
|
|
27
|
+
} else if (accessorKey) {
|
|
28
|
+
derived[colId] = (a, b, dir) => useSorting.defaultCompare(a[accessorKey], b[accessorKey], dir, nullsMode);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { ...derived, ...sorting == null ? void 0 : sorting.columnComparators };
|
|
32
|
+
}, [sorting == null ? void 0 : sorting.columns, sorting == null ? void 0 : sorting.columnComparators, nullsMode]);
|
|
15
33
|
const s = useSorting.useSorting({
|
|
16
34
|
data,
|
|
17
|
-
sortBy: (
|
|
18
|
-
sortDirection: (
|
|
35
|
+
sortBy: (_b = sorting == null ? void 0 : sorting.sortBy) != null ? _b : null,
|
|
36
|
+
sortDirection: (_c = sorting == null ? void 0 : sorting.direction) != null ? _c : null,
|
|
19
37
|
state: sorting == null ? void 0 : sorting.state,
|
|
20
38
|
onStateChange: sorting == null ? void 0 : sorting.onStateChange,
|
|
21
|
-
columnComparators:
|
|
22
|
-
nulls:
|
|
39
|
+
columnComparators: mergedComparators,
|
|
40
|
+
nulls: nullsMode,
|
|
23
41
|
allowUnsort: (_d = sorting == null ? void 0 : sorting.allowUnsort) != null ? _d : true
|
|
24
42
|
});
|
|
25
43
|
const p = usePagination.usePagination({
|
|
26
44
|
data: s.sortedData,
|
|
27
45
|
skip: (_e = pagination == null ? void 0 : pagination.skip) != null ? _e : 0,
|
|
28
|
-
take: (_f = pagination == null ? void 0 : pagination.take) != null ? _f :
|
|
46
|
+
take: (_f = pagination == null ? void 0 : pagination.take) != null ? _f : Math.max(s.sortedData.length, 1),
|
|
29
47
|
state: pagination == null ? void 0 : pagination.state,
|
|
30
48
|
onStateChange: pagination == null ? void 0 : pagination.onStateChange
|
|
31
49
|
});
|
|
32
50
|
react.useEffect(() => {
|
|
51
|
+
if (!hasPagination) return;
|
|
33
52
|
if (!resetPageOnSortChange) return;
|
|
34
53
|
p.resetPage();
|
|
35
|
-
}, [resetPageOnSortChange, s.sortState.sortBy, s.sortState.sortDirection]);
|
|
36
|
-
const rows = react.useMemo(
|
|
54
|
+
}, [hasPagination, resetPageOnSortChange, s.sortState.sortBy, s.sortState.sortDirection]);
|
|
55
|
+
const rows = react.useMemo(
|
|
56
|
+
() => hasPagination ? p.paginatedData : s.sortedData,
|
|
57
|
+
[hasPagination, p.paginatedData, s.sortedData]
|
|
58
|
+
);
|
|
37
59
|
return {
|
|
38
60
|
rows,
|
|
39
61
|
totalCount: s.sortedData.length,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ColumnDef } from '@tanstack/react-table';
|
|
1
2
|
import type { PageChangeEvent } from '../components/pagination/Pagination';
|
|
2
3
|
import { type PaginationState } from './usePagination';
|
|
3
4
|
import { type SortDirection, type SortState, type ColumnComparators } from './useSorting';
|
|
@@ -10,13 +11,14 @@ export interface UseTableDataProps<T> {
|
|
|
10
11
|
onStateChange?: (next: PaginationState) => void;
|
|
11
12
|
};
|
|
12
13
|
sorting?: {
|
|
13
|
-
sortBy?:
|
|
14
|
+
sortBy?: string | null;
|
|
14
15
|
direction?: SortDirection;
|
|
15
16
|
state?: SortState<T>;
|
|
16
17
|
onStateChange?: (next: SortState<T>) => void;
|
|
17
18
|
columnComparators?: ColumnComparators<T>;
|
|
18
19
|
nulls?: 'first' | 'last';
|
|
19
20
|
allowUnsort?: boolean;
|
|
21
|
+
columns?: ReadonlyArray<ColumnDef<T, any>>;
|
|
20
22
|
};
|
|
21
23
|
/**
|
|
22
24
|
* Resets to page 1 whenever sorting changes (typical UX).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import {
|
|
2
|
+
import { useMemo, useEffect } from 'react';
|
|
3
3
|
import { usePagination } from './usePagination';
|
|
4
|
-
import { useSorting } from './useSorting';
|
|
4
|
+
import { useSorting, defaultCompare } from './useSorting';
|
|
5
5
|
|
|
6
6
|
function useTableData({
|
|
7
7
|
data = [],
|
|
@@ -10,28 +10,50 @@ function useTableData({
|
|
|
10
10
|
resetPageOnSortChange = true
|
|
11
11
|
}) {
|
|
12
12
|
var _a, _b, _c, _d, _e, _f;
|
|
13
|
+
const hasPagination = pagination != null;
|
|
14
|
+
const nullsMode = (_a = sorting == null ? void 0 : sorting.nulls) != null ? _a : "last";
|
|
15
|
+
const mergedComparators = useMemo(() => {
|
|
16
|
+
var _a2, _b2;
|
|
17
|
+
const derived = {};
|
|
18
|
+
for (const col of (_a2 = sorting == null ? void 0 : sorting.columns) != null ? _a2 : []) {
|
|
19
|
+
const colId = (_b2 = col.id) != null ? _b2 : col.accessorKey;
|
|
20
|
+
if (!colId) continue;
|
|
21
|
+
const accessorFn = col.accessorFn;
|
|
22
|
+
const accessorKey = col.accessorKey;
|
|
23
|
+
if (accessorFn) {
|
|
24
|
+
derived[colId] = (a, b, dir) => defaultCompare(accessorFn(a, 0), accessorFn(b, 0), dir, nullsMode);
|
|
25
|
+
} else if (accessorKey) {
|
|
26
|
+
derived[colId] = (a, b, dir) => defaultCompare(a[accessorKey], b[accessorKey], dir, nullsMode);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { ...derived, ...sorting == null ? void 0 : sorting.columnComparators };
|
|
30
|
+
}, [sorting == null ? void 0 : sorting.columns, sorting == null ? void 0 : sorting.columnComparators, nullsMode]);
|
|
13
31
|
const s = useSorting({
|
|
14
32
|
data,
|
|
15
|
-
sortBy: (
|
|
16
|
-
sortDirection: (
|
|
33
|
+
sortBy: (_b = sorting == null ? void 0 : sorting.sortBy) != null ? _b : null,
|
|
34
|
+
sortDirection: (_c = sorting == null ? void 0 : sorting.direction) != null ? _c : null,
|
|
17
35
|
state: sorting == null ? void 0 : sorting.state,
|
|
18
36
|
onStateChange: sorting == null ? void 0 : sorting.onStateChange,
|
|
19
|
-
columnComparators:
|
|
20
|
-
nulls:
|
|
37
|
+
columnComparators: mergedComparators,
|
|
38
|
+
nulls: nullsMode,
|
|
21
39
|
allowUnsort: (_d = sorting == null ? void 0 : sorting.allowUnsort) != null ? _d : true
|
|
22
40
|
});
|
|
23
41
|
const p = usePagination({
|
|
24
42
|
data: s.sortedData,
|
|
25
43
|
skip: (_e = pagination == null ? void 0 : pagination.skip) != null ? _e : 0,
|
|
26
|
-
take: (_f = pagination == null ? void 0 : pagination.take) != null ? _f :
|
|
44
|
+
take: (_f = pagination == null ? void 0 : pagination.take) != null ? _f : Math.max(s.sortedData.length, 1),
|
|
27
45
|
state: pagination == null ? void 0 : pagination.state,
|
|
28
46
|
onStateChange: pagination == null ? void 0 : pagination.onStateChange
|
|
29
47
|
});
|
|
30
48
|
useEffect(() => {
|
|
49
|
+
if (!hasPagination) return;
|
|
31
50
|
if (!resetPageOnSortChange) return;
|
|
32
51
|
p.resetPage();
|
|
33
|
-
}, [resetPageOnSortChange, s.sortState.sortBy, s.sortState.sortDirection]);
|
|
34
|
-
const rows = useMemo(
|
|
52
|
+
}, [hasPagination, resetPageOnSortChange, s.sortState.sortBy, s.sortState.sortDirection]);
|
|
53
|
+
const rows = useMemo(
|
|
54
|
+
() => hasPagination ? p.paginatedData : s.sortedData,
|
|
55
|
+
[hasPagination, p.paginatedData, s.sortedData]
|
|
56
|
+
);
|
|
35
57
|
return {
|
|
36
58
|
rows,
|
|
37
59
|
totalCount: s.sortedData.length,
|