@dbcdk/react-components 0.0.26 → 0.0.28
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/__stories__/_data/table.d.ts +1 -1
- package/dist/components/__stories__/_data/table.js +11 -5
- package/dist/components/accordion/Accordion.module.css +3 -3
- package/dist/components/accordion/components/AccordionRow.module.css +5 -1
- package/dist/components/headline/Headline.module.css +15 -44
- package/dist/components/nav-bar/NavBar.module.css +1 -1
- package/dist/components/panel/Panel.module.css +2 -2
- package/dist/components/table/Table.d.ts +3 -64
- package/dist/components/table/Table.js +20 -150
- package/dist/components/table/Table.module.css +38 -6
- package/dist/components/table/Table.types.d.ts +58 -0
- package/dist/components/table/Table.types.js +1 -0
- package/dist/components/table/TanstackTable.d.ts +1 -1
- package/dist/components/table/TanstackTable.js +0 -1
- package/dist/components/table/components/TableBody.d.ts +19 -0
- package/dist/components/table/components/TableBody.js +10 -0
- package/dist/components/table/components/TableCell.d.ts +9 -0
- package/dist/components/table/components/TableCell.js +7 -0
- package/dist/components/table/components/TableHeader.d.ts +16 -0
- package/dist/components/table/components/TableHeader.js +7 -0
- package/dist/components/table/components/TableHeaderCell.d.ts +12 -0
- package/dist/components/table/components/TableHeaderCell.js +24 -0
- package/dist/components/table/components/TableLoadingBody.d.ts +10 -0
- package/dist/components/table/components/TableLoadingBody.js +10 -0
- package/dist/components/table/components/TablePagination.d.ts +0 -0
- package/dist/components/table/components/TablePagination.js +1 -0
- package/dist/components/table/components/TableRow.d.ts +19 -0
- package/dist/components/table/components/TableRow.js +38 -0
- package/dist/components/table/components/TableSelectionCell.d.ts +9 -0
- package/dist/components/table/components/TableSelectionCell.js +15 -0
- package/dist/components/table/hooks/useTableRowInteractions.d.ts +15 -0
- package/dist/components/table/hooks/useTableRowInteractions.js +25 -0
- package/dist/components/table/table.classes.d.ts +10 -0
- package/dist/components/table/table.classes.js +23 -0
- package/dist/components/table/table.utils.d.ts +7 -4
- package/dist/components/table/table.utils.js +14 -20
- package/dist/components/table/tanstackTable.utils.d.ts +1 -2
- package/dist/components/table/tanstackTable.utils.js +3 -2
- package/dist/utils/date/formatDate.d.ts +1 -1
- package/dist/utils/date/formatDate.js +2 -2
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { Circle } from '../../../components/circle/Circle';
|
|
3
3
|
import { Table } from '../../../components/table/Table';
|
|
4
4
|
const sources = ['onix.vendor-x', 'onix.vendor-y', 'cover.provider-z'];
|
|
5
5
|
const statuses = ['Completed', 'Running', 'Failed'];
|
|
@@ -40,10 +40,16 @@ export const STORY_TABLE_COLUMNS = [
|
|
|
40
40
|
header: 'Status',
|
|
41
41
|
accessor: 'status',
|
|
42
42
|
sortable: true,
|
|
43
|
-
render: (row) => (_jsxs("span", { className: "dbc-flex dbc-flex-row dbc-flex-wrap dbc-gap-xs", children: [row.status === 'Completed' && (_jsx(
|
|
43
|
+
render: (row) => (_jsxs("span", { className: "dbc-flex dbc-flex-row dbc-flex-wrap dbc-gap-xs", children: [row.status === 'Completed' && (_jsx(Circle, { size: "xs", severity: "success", children: "Fuldf\u00F8rt" })), row.status === 'Running' && (_jsx(Circle, { pulse: true, size: "xs", severity: "info", children: "K\u00F8rer" })), row.status === 'Failed' && (_jsx(Circle, { size: "xs", severity: "error", children: "Fejlet" }))] })),
|
|
44
44
|
},
|
|
45
|
-
{
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
{
|
|
46
|
+
id: 'updated',
|
|
47
|
+
header: 'Opdateret',
|
|
48
|
+
accessor: 'updated',
|
|
49
|
+
sortable: true,
|
|
50
|
+
align: 'right',
|
|
51
|
+
},
|
|
52
|
+
{ id: 'warnings', header: 'Advarsler', accessor: 'warnings', sortable: true, align: 'right' },
|
|
53
|
+
{ id: 'failed', header: 'Fejlet', accessor: 'failed', sortable: true, align: 'right' },
|
|
48
54
|
];
|
|
49
55
|
export const SampleTable = () => (_jsx(Table, { fillViewport: true, data: STORY_TABLE_DATA(), columns: STORY_TABLE_COLUMNS, dataKey: "runId", variant: "embedded" }));
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
/* Size variables (consumed by AccordionRow) */
|
|
12
12
|
.sm {
|
|
13
|
-
--acc-trigger-py: var(--spacing-
|
|
14
|
-
--acc-trigger-px: var(--spacing-
|
|
15
|
-
--acc-content-py: var(--spacing-
|
|
13
|
+
--acc-trigger-py: var(--spacing-xs);
|
|
14
|
+
--acc-trigger-px: var(--spacing-sm);
|
|
15
|
+
--acc-content-py: var(--spacing-xs);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
.md {
|
|
@@ -34,7 +34,6 @@
|
|
|
34
34
|
min-width: 0;
|
|
35
35
|
flex: 1 1 auto;
|
|
36
36
|
overflow: hidden;
|
|
37
|
-
justify-content: space-between;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
.icon {
|
|
@@ -43,6 +42,11 @@
|
|
|
43
42
|
align-items: center;
|
|
44
43
|
}
|
|
45
44
|
|
|
45
|
+
.icon svg {
|
|
46
|
+
height: var(--icon-size-sm);
|
|
47
|
+
width: var(--icon-size-sm);
|
|
48
|
+
}
|
|
49
|
+
|
|
46
50
|
.chevron {
|
|
47
51
|
width: var(--icon-size-md);
|
|
48
52
|
height: var(--icon-size-md);
|
|
@@ -6,19 +6,25 @@
|
|
|
6
6
|
max-width: 100%;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
/* Base headline
|
|
9
|
+
/* Base headline */
|
|
10
10
|
.headline {
|
|
11
11
|
position: relative;
|
|
12
12
|
display: inline-flex;
|
|
13
13
|
align-items: center;
|
|
14
14
|
gap: var(--spacing-xs);
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
/* Typography */
|
|
17
|
+
font-weight: var(--font-weight-medium, 500);
|
|
16
18
|
letter-spacing: var(--letter-spacing-tight);
|
|
17
|
-
color: inherit;
|
|
18
19
|
line-height: var(--line-height-tight);
|
|
20
|
+
color: inherit;
|
|
21
|
+
|
|
22
|
+
/* Behaviour */
|
|
19
23
|
transition: color var(--transition-fast) var(--ease-standard);
|
|
24
|
+
min-width: 0; /* required for truncation inside flex */
|
|
20
25
|
}
|
|
21
26
|
|
|
27
|
+
/* Tone overrides */
|
|
22
28
|
.tone-dark .headline {
|
|
23
29
|
color: var(--color-fg-default);
|
|
24
30
|
}
|
|
@@ -31,6 +37,7 @@
|
|
|
31
37
|
margin: 0;
|
|
32
38
|
}
|
|
33
39
|
|
|
40
|
+
/* Marker variant */
|
|
34
41
|
.headline.marker {
|
|
35
42
|
padding-inline-start: calc(var(--border-width-thick) + var(--spacing-sm));
|
|
36
43
|
}
|
|
@@ -48,8 +55,7 @@
|
|
|
48
55
|
pointer-events: none;
|
|
49
56
|
}
|
|
50
57
|
|
|
51
|
-
/* Subheadline
|
|
52
|
-
so it works on both light and dark text surfaces. */
|
|
58
|
+
/* Subheadline */
|
|
53
59
|
.subHeadline {
|
|
54
60
|
color: inherit;
|
|
55
61
|
opacity: 0.85;
|
|
@@ -58,55 +64,20 @@
|
|
|
58
64
|
line-height: var(--line-height-normal);
|
|
59
65
|
}
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
position: relative;
|
|
63
|
-
display: inline-flex;
|
|
64
|
-
align-items: center;
|
|
65
|
-
gap: var(--spacing-xs);
|
|
66
|
-
font-weight: var(--font-weight, var(--font-weight-bold));
|
|
67
|
-
letter-spacing: var(--letter-spacing-tight);
|
|
68
|
-
color: inherit;
|
|
69
|
-
line-height: var(--line-height-tight);
|
|
70
|
-
transition: color var(--transition-fast) var(--ease-standard);
|
|
71
|
-
|
|
72
|
-
/* Needed so truncation works inside flex parents */
|
|
73
|
-
min-width: 0;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/* Truncated variant (single line with ellipsis) */
|
|
77
|
-
.truncate {
|
|
78
|
-
white-space: nowrap;
|
|
79
|
-
overflow: hidden;
|
|
80
|
-
text-overflow: ellipsis;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.headline {
|
|
84
|
-
position: relative;
|
|
85
|
-
display: inline-flex;
|
|
86
|
-
align-items: center;
|
|
87
|
-
gap: var(--spacing-xs);
|
|
88
|
-
font-weight: var(--font-weight, var(--font-weight-bold));
|
|
89
|
-
letter-spacing: var(--letter-spacing-tight);
|
|
90
|
-
color: inherit;
|
|
91
|
-
line-height: var(--line-height-tight);
|
|
92
|
-
transition: color var(--transition-fast) var(--ease-standard);
|
|
93
|
-
|
|
94
|
-
/* helps inside flex parents */
|
|
95
|
-
min-width: 0;
|
|
96
|
-
}
|
|
97
|
-
|
|
67
|
+
/* Icon */
|
|
98
68
|
.icon {
|
|
99
69
|
flex: 0 0 auto;
|
|
100
70
|
display: inline-flex;
|
|
101
71
|
align-items: center;
|
|
102
72
|
}
|
|
103
73
|
|
|
104
|
-
/*
|
|
74
|
+
/* Text wrapper (allows shrinking inside flex layouts) */
|
|
105
75
|
.text {
|
|
106
|
-
min-width: 0;
|
|
107
76
|
flex: 1 1 auto;
|
|
77
|
+
min-width: 0;
|
|
108
78
|
}
|
|
109
79
|
|
|
80
|
+
/* Text behaviour */
|
|
110
81
|
.truncate {
|
|
111
82
|
overflow: hidden;
|
|
112
83
|
white-space: nowrap;
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
font-size: var(--font-size-sm);
|
|
47
47
|
text-decoration: none;
|
|
48
48
|
border-radius: var(--border-radius-default);
|
|
49
|
-
padding-block:
|
|
49
|
+
padding-block: var(--spacing-xs);
|
|
50
50
|
padding-inline: var(--spacing-sm);
|
|
51
51
|
transition:
|
|
52
52
|
background-color var(--transition-fast) var(--ease-standard),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
.container {
|
|
2
|
-
border:
|
|
2
|
+
border: var(--border-width-thin) solid var(--color-border-default);
|
|
3
3
|
border-radius: var(--border-radius-default);
|
|
4
4
|
background-color: var(--color-bg-surface);
|
|
5
5
|
box-sizing: border-box;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
.header {
|
|
11
|
-
border-bottom:
|
|
11
|
+
border-bottom: var(--border-width-thin) solid var(--color-border-default);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
.content {
|
|
@@ -1,64 +1,3 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { ViewMode } from '../../hooks/useTableSettings';
|
|
5
|
-
import { TableEmptyConfig } from './components/empty-state/EmptyState';
|
|
6
|
-
import { SortDirection } from './table.utils';
|
|
7
|
-
export interface ColumnItem<T> {
|
|
8
|
-
id: string;
|
|
9
|
-
header: string | (() => ReactNode);
|
|
10
|
-
accessor?: keyof T;
|
|
11
|
-
sortable?: boolean;
|
|
12
|
-
sortFunction?: (a: T, b: T) => -1 | 0 | 1;
|
|
13
|
-
render?: (item: T) => ReactNode;
|
|
14
|
-
hidden?: boolean;
|
|
15
|
-
align?: 'left' | 'right' | 'center';
|
|
16
|
-
verticalAlign?: 'top' | 'middle' | 'bottom';
|
|
17
|
-
divider?: 'right' | 'left';
|
|
18
|
-
allowWrap?: boolean;
|
|
19
|
-
emptyPlaceholder?: ReactNode;
|
|
20
|
-
canHide?: boolean;
|
|
21
|
-
severity?: any;
|
|
22
|
-
}
|
|
23
|
-
type HeaderExtrasArgs<T> = {
|
|
24
|
-
column: ColumnItem<T>;
|
|
25
|
-
index: number;
|
|
26
|
-
};
|
|
27
|
-
export type TableVariant = 'primary' | 'embedded';
|
|
28
|
-
export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'onMouseEnter'> & {
|
|
29
|
-
data: T[];
|
|
30
|
-
dataKey: keyof T;
|
|
31
|
-
columns: ColumnItem<T>[];
|
|
32
|
-
selectedRows?: Set<number | string>;
|
|
33
|
-
selectionMode?: 'single' | 'multiple';
|
|
34
|
-
allRowsSelected?: boolean;
|
|
35
|
-
onRowClick?: (row: T) => void;
|
|
36
|
-
onRowMouseEnter?: (row: T) => void;
|
|
37
|
-
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
38
|
-
onSelectAllRows?: (isSelected: boolean) => void;
|
|
39
|
-
onSortChange?: (column: ColumnItem<T>, direction: SortDirection) => void;
|
|
40
|
-
sortById?: string;
|
|
41
|
-
sortDirection?: SortDirection;
|
|
42
|
-
loading?: boolean;
|
|
43
|
-
headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
|
|
44
|
-
gridTemplateColumns?: string;
|
|
45
|
-
toolbar?: ReactNode;
|
|
46
|
-
striped?: boolean;
|
|
47
|
-
fillViewport?: boolean;
|
|
48
|
-
viewportBottomOffset?: number;
|
|
49
|
-
viewportMin?: number;
|
|
50
|
-
viewportIncludeMarginTop?: boolean;
|
|
51
|
-
take?: number;
|
|
52
|
-
skip?: number;
|
|
53
|
-
paginationPlacement?: 'top' | 'bottom';
|
|
54
|
-
totalItemsCount?: number;
|
|
55
|
-
onPageChange?: (e: PageChangeEvent) => void;
|
|
56
|
-
variant?: TableVariant;
|
|
57
|
-
size?: 'sm' | 'md';
|
|
58
|
-
getRowSeverity?: (row: T) => Severity | undefined;
|
|
59
|
-
showFirstLast?: boolean;
|
|
60
|
-
viewMode?: ViewMode;
|
|
61
|
-
emptyConfig?: TableEmptyConfig;
|
|
62
|
-
};
|
|
63
|
-
export declare function Table<T extends Record<string, any>>({ data, columns, selectedRows, onRowSelect, selectionMode, onSortChange, onRowClick, onRowMouseEnter, sortById, sortDirection, dataKey, headerExtras, gridTemplateColumns, toolbar, striped, fillViewport, viewportBottomOffset, viewportMin, viewportIncludeMarginTop, take, skip, paginationPlacement, totalItemsCount, onPageChange, loading, variant, size, getRowSeverity, showFirstLast, allRowsSelected, onSelectAllRows, viewMode, emptyConfig, ...rest }: TableProps<T>): JSX.Element;
|
|
64
|
-
export {};
|
|
1
|
+
import type { JSX } from 'react';
|
|
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, gridTemplateColumns, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement, showFirstLast, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
|
|
@@ -1,161 +1,31 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { ArrowDown, ArrowUp } from 'lucide-react';
|
|
4
3
|
import { useCallback, useMemo } from 'react';
|
|
5
|
-
import { Checkbox } from '../../components/forms/checkbox/Checkbox';
|
|
6
4
|
import { Pagination } from '../../components/pagination/Pagination';
|
|
7
|
-
import { SkeletonLoaderItem } from '../../components/skeleton-loader/skeleton-loader-item/SkeletonLoaderItem';
|
|
8
|
-
import { SeverityBgColor } from '../../constants/severity';
|
|
9
5
|
import { TableEmptyState } from './components/empty-state/EmptyState';
|
|
6
|
+
import { TableBody } from './components/TableBody';
|
|
7
|
+
import { TableHeader } from './components/TableHeader';
|
|
8
|
+
import { TableLoadingBody } from './components/TableLoadingBody';
|
|
9
|
+
import { cx } from './table.classes';
|
|
10
10
|
import styles from './Table.module.css';
|
|
11
|
-
import {
|
|
12
|
-
function
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
if (hasSelection)
|
|
16
|
-
parts.push('34px');
|
|
17
|
-
for (let i = 0; i < colCount; i++)
|
|
18
|
-
parts.push('minmax(120px, 1fr)');
|
|
19
|
-
return parts.join(' ');
|
|
20
|
-
}
|
|
21
|
-
export function Table({ data, columns, selectedRows, onRowSelect, selectionMode = 'single', onSortChange, onRowClick, onRowMouseEnter, sortById, sortDirection, dataKey, headerExtras, gridTemplateColumns, toolbar, striped, fillViewport = false, viewportBottomOffset, viewportMin, viewportIncludeMarginTop, take, skip, paginationPlacement = 'bottom', totalItemsCount, onPageChange, loading, variant = 'primary', size = 'md', getRowSeverity, showFirstLast = false, allRowsSelected, onSelectAllRows, viewMode, emptyConfig, ...rest }) {
|
|
22
|
-
void viewportBottomOffset;
|
|
23
|
-
void viewportMin;
|
|
24
|
-
void viewportIncludeMarginTop;
|
|
25
|
-
const filteredColumns = useMemo(() => getVisibleColumns(columns), [columns]);
|
|
26
|
-
const handlePageChange = useCallback((e) => onPageChange === null || onPageChange === void 0 ? void 0 : onPageChange(e), [onPageChange]);
|
|
27
|
-
const hasSelection = Boolean(selectedRows && onRowSelect && dataKey);
|
|
11
|
+
import { buildDefaultGridTemplate, getVisibleColumns } from './table.utils';
|
|
12
|
+
export function Table({ data, dataKey, columns, selectedRows, selectionMode = 'single', allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant = 'primary', size = 'md', viewMode, striped, fillViewport = false, gridTemplateColumns, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement = 'bottom', showFirstLast = false, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }) {
|
|
13
|
+
const visibleColumns = useMemo(() => getVisibleColumns(columns), [columns]);
|
|
14
|
+
const hasSelection = Boolean(selectedRows && onRowSelect);
|
|
28
15
|
const template = useMemo(() => {
|
|
29
|
-
return (gridTemplateColumns !== null && gridTemplateColumns !== void 0 ? gridTemplateColumns : buildDefaultGridTemplate({
|
|
30
|
-
|
|
16
|
+
return (gridTemplateColumns !== null && gridTemplateColumns !== void 0 ? gridTemplateColumns : buildDefaultGridTemplate({
|
|
17
|
+
hasSelection,
|
|
18
|
+
colCount: visibleColumns.length,
|
|
19
|
+
}));
|
|
20
|
+
}, [gridTemplateColumns, hasSelection, visibleColumns.length]);
|
|
31
21
|
const gridStyle = useMemo(() => ({ ['--grid-template']: template }), [template]);
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (!onSortChange || !column.sortable)
|
|
40
|
-
return;
|
|
41
|
-
const nextDir = getNextSortDirection(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
|
|
42
|
-
onSortChange(column, nextDir);
|
|
43
|
-
};
|
|
44
|
-
const dividerClass = column.divider === 'left'
|
|
45
|
-
? styles.dividerLeft
|
|
46
|
-
: column.divider === 'right'
|
|
47
|
-
? styles.dividerRight
|
|
48
|
-
: '';
|
|
49
|
-
return (_jsxs("div", { className: [styles.headerCell, dividerClass].filter(Boolean).join(' '), role: "columnheader", "aria-sort": ariaSort, "data-align": align, "data-divider": column.divider, children: [_jsx("div", { className: [
|
|
50
|
-
styles.thInner,
|
|
51
|
-
align === 'right' ? styles.thInnerRight : '',
|
|
52
|
-
align === 'center' ? styles.thInnerCenter : '',
|
|
53
|
-
]
|
|
54
|
-
.filter(Boolean)
|
|
55
|
-
.join(' '), children: _jsx("div", { className: [
|
|
56
|
-
styles.thMain,
|
|
57
|
-
align === 'right' ? styles.thMainRight : '',
|
|
58
|
-
align === 'center' ? styles.thMainCenter : '',
|
|
59
|
-
]
|
|
60
|
-
.filter(Boolean)
|
|
61
|
-
.join(' '), children: column.sortable ? (_jsxs("button", { type: "button", className: [
|
|
62
|
-
styles.thButton,
|
|
63
|
-
align === 'right' ? styles.thButtonRight : '',
|
|
64
|
-
align === 'center' ? styles.thButtonCenter : '',
|
|
65
|
-
]
|
|
66
|
-
.filter(Boolean)
|
|
67
|
-
.join(' '), onClick: toggleSort, onKeyDown: e => {
|
|
68
|
-
if (shouldToggleOnKey(e.key)) {
|
|
69
|
-
e.preventDefault();
|
|
70
|
-
toggleSort();
|
|
71
|
-
}
|
|
72
|
-
}, children: [_jsx("span", { className: [
|
|
73
|
-
styles.thLabel,
|
|
74
|
-
align === 'right' ? styles.thLabelRight : '',
|
|
75
|
-
align === 'center' ? styles.thLabelCenter : '',
|
|
76
|
-
]
|
|
77
|
-
.filter(Boolean)
|
|
78
|
-
.join(' '), children: getHeaderLabel(column.header) }), _jsxs("span", { className: styles.sortIndicator, "aria-hidden": "true", children: [active && sortDirection === 'asc' && _jsx(ArrowUp, {}), active && sortDirection === 'desc' && (_jsx(ArrowDown, { className: styles.descending })), !active && (_jsx(ArrowDown, { className: `${styles.descending} ${styles.inActiveSort}` }))] })] })) : (_jsx("span", { className: [
|
|
79
|
-
styles.thLabel,
|
|
80
|
-
align === 'right' ? styles.thLabelRight : '',
|
|
81
|
-
align === 'center' ? styles.thLabelCenter : '',
|
|
82
|
-
]
|
|
83
|
-
.filter(Boolean)
|
|
84
|
-
.join(' '), children: getHeaderLabel(column.header) })) }) }), extraContent != null ? (_jsx("div", { className: styles.thOverlayExtras, children: extraContent })) : null] }, column.id));
|
|
85
|
-
})] }));
|
|
86
|
-
const loadingBodyEl = (_jsx("div", { className: styles.body, role: "rowgroup", children: Array.from({ length: take !== null && take !== void 0 ? take : 5 }).map((_, rowIndex) => (_jsxs("div", { className: styles.row, style: gridStyle, role: "row", children: [hasSelection ? (_jsx("div", { className: `${styles.cell} ${styles.selectionCell}`, role: "cell" })) : null, filteredColumns.map(column => {
|
|
87
|
-
var _a;
|
|
88
|
-
const dividerClass = column.divider === 'left'
|
|
89
|
-
? styles.dividerLeft
|
|
90
|
-
: column.divider === 'right'
|
|
91
|
-
? styles.dividerRight
|
|
92
|
-
: '';
|
|
93
|
-
return (_jsx("div", { className: [styles.cell, dividerClass].filter(Boolean).join(' '), role: "cell", "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, children: _jsx("div", { className: styles.cellContent, children: _jsx("div", { className: styles.cellValueEllipsis, children: _jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }) }) }, column.id));
|
|
94
|
-
})] }, `loading-row-${rowIndex}`))) }));
|
|
95
|
-
const dataBodyEl = (_jsx("div", { className: `${styles.body} ${striped ? styles.striped : ''}`, role: "rowgroup", children: data.map(row => {
|
|
96
|
-
const rowSeverity = getRowSeverity === null || getRowSeverity === void 0 ? void 0 : getRowSeverity(row);
|
|
97
|
-
const rowId = row[dataKey];
|
|
98
|
-
const isSelected = Boolean(selectedRows === null || selectedRows === void 0 ? void 0 : selectedRows.has(rowId));
|
|
99
|
-
return (_jsxs("div", { className: [
|
|
100
|
-
styles.row,
|
|
101
|
-
onRowClick ? styles.clickableRow : '',
|
|
102
|
-
isSelected ? styles.selectedRow : '',
|
|
103
|
-
rowSeverity ? styles.severity : '',
|
|
104
|
-
]
|
|
105
|
-
.filter(Boolean)
|
|
106
|
-
.join(' '), style: {
|
|
107
|
-
...gridStyle,
|
|
108
|
-
['--row-severity-color']: rowSeverity
|
|
109
|
-
? SeverityBgColor[rowSeverity]
|
|
110
|
-
: undefined,
|
|
111
|
-
}, role: "row", tabIndex: onRowClick ? 0 : -1, onKeyDown: e => {
|
|
112
|
-
if (!onRowClick)
|
|
113
|
-
return;
|
|
114
|
-
if (shouldToggleOnKey(e.key)) {
|
|
115
|
-
e.preventDefault();
|
|
116
|
-
onRowClick(row);
|
|
117
|
-
}
|
|
118
|
-
}, onMouseEnter: () => onRowMouseEnter === null || onRowMouseEnter === void 0 ? void 0 : onRowMouseEnter(row), onClick: e => {
|
|
119
|
-
const canSelect = Boolean(selectedRows && onRowSelect && dataKey);
|
|
120
|
-
if (isModifierClick(e) && canSelect) {
|
|
121
|
-
e.preventDefault();
|
|
122
|
-
e.stopPropagation();
|
|
123
|
-
onRowSelect(rowId, !selectedRows.has(rowId));
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row);
|
|
127
|
-
}, children: [hasSelection && (_jsx("div", { className: `${styles.cell} ${styles.selectionCell}`, role: "cell", children: _jsx(Checkbox, { variant: "primary", checked: selectedRows.has(rowId), size: "sm", onChange: (checked, e) => {
|
|
128
|
-
e.stopPropagation();
|
|
129
|
-
onRowSelect === null || onRowSelect === void 0 ? void 0 : onRowSelect(rowId, checked);
|
|
130
|
-
} }) })), filteredColumns.map(column => {
|
|
131
|
-
var _a;
|
|
132
|
-
const dividerClass = column.divider === 'left'
|
|
133
|
-
? styles.dividerLeft
|
|
134
|
-
: column.divider === 'right'
|
|
135
|
-
? styles.dividerRight
|
|
136
|
-
: '';
|
|
137
|
-
const allowWrap = shouldAllowWrap(column.allowWrap, isSelected, viewMode);
|
|
138
|
-
const cellValue = getCellDisplayValue(row, column);
|
|
139
|
-
return (_jsx("div", { className: [
|
|
140
|
-
styles.cell,
|
|
141
|
-
allowWrap ? styles.allowWrap : styles.nowrap,
|
|
142
|
-
dividerClass,
|
|
143
|
-
]
|
|
144
|
-
.filter(Boolean)
|
|
145
|
-
.join(' '), role: "cell", "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, children: _jsx("div", { className: styles.cellContent, children: allowWrap ? (cellValue) : (_jsx("div", { className: styles.cellValueEllipsis, children: cellValue })) }) }, column.id));
|
|
146
|
-
})] }, `gridRow-${rowId}`));
|
|
147
|
-
}) }));
|
|
148
|
-
const bodyContent = loading && !data.length ? loadingBodyEl : dataBodyEl;
|
|
149
|
-
const tableClassName = [
|
|
150
|
-
styles.tableRoot,
|
|
151
|
-
styles[variant],
|
|
152
|
-
styles[size],
|
|
153
|
-
getRowSeverity ? styles.severityTable : '',
|
|
154
|
-
]
|
|
155
|
-
.filter(Boolean)
|
|
156
|
-
.join(' ');
|
|
157
|
-
const tableShell = (_jsx("div", { ...rest, className: tableClassName, role: "table", "aria-rowcount": data.length, children: _jsxs("div", { className: styles.tableContent, children: [_jsx("div", { className: styles.header, role: "rowgroup", children: headerEl }), _jsx("div", { className: styles.bodyScroll, children: !data.length && !loading ? (_jsx("div", { className: styles.emptyStateSlot, children: _jsx(TableEmptyState, { config: emptyConfig }) })) : (bodyContent) })] }) }));
|
|
158
|
-
const paginationEl = onPageChange && data.length > 0 ? (_jsx("div", { className: `${styles.paginationSlot} ${paginationPlacement === 'top' ? styles.paginationSlotTop : ''}`, children: _jsx(Pagination, { itemsCount: totalItemsCount, take: take, skip: skip, onPageChange: handlePageChange, showFirstLast: showFirstLast }) })) : null;
|
|
22
|
+
const handlePageChange = useCallback((e) => {
|
|
23
|
+
onPageChange === null || onPageChange === void 0 ? void 0 : onPageChange(e);
|
|
24
|
+
}, [onPageChange]);
|
|
25
|
+
const bodyContent = loading && !data.length ? (_jsx(TableLoadingBody, { rows: take !== null && take !== void 0 ? take : 5, columns: visibleColumns, hasSelection: hasSelection, gridStyle: gridStyle })) : (_jsx(TableBody, { data: data, dataKey: dataKey, columns: visibleColumns, gridStyle: gridStyle, striped: striped, selectedRows: selectedRows, hasSelection: hasSelection, viewMode: viewMode, getRowSeverity: getRowSeverity, onRowClick: onRowClick, onRowMouseEnter: onRowMouseEnter, onRowSelect: onRowSelect }));
|
|
26
|
+
const paginationEl = onPageChange && data.length > 0 ? (_jsx("div", { className: cx(styles.paginationSlot, paginationPlacement === 'top' && styles.paginationSlotTop), children: _jsx(Pagination, { itemsCount: totalItemsCount, take: take, skip: skip, onPageChange: handlePageChange, showFirstLast: showFirstLast }) })) : null;
|
|
27
|
+
const tableClassName = cx(styles.tableRoot, styles[variant], styles[size], getRowSeverity && styles.severityTable);
|
|
28
|
+
const tableShell = (_jsx("div", { ...rest, className: tableClassName, role: "table", "aria-rowcount": data.length, children: _jsxs("div", { className: styles.tableContent, children: [_jsx("div", { className: styles.header, role: "rowgroup", children: _jsx(TableHeader, { columns: visibleColumns, gridStyle: gridStyle, hasSelection: hasSelection, selectionMode: selectionMode, allRowsSelected: allRowsSelected, onSelectAllRows: onSelectAllRows, sortById: sortById, sortDirection: sortDirection, onSortChange: onSortChange, headerExtras: headerExtras }) }), _jsx("div", { className: styles.bodyScroll, children: !data.length && !loading ? (_jsx("div", { className: styles.emptyStateSlot, children: _jsx(TableEmptyState, { config: emptyConfig }) })) : (bodyContent) })] }) }));
|
|
159
29
|
if (fillViewport) {
|
|
160
30
|
return (_jsxs("div", { className: styles.fillViewportRoot, style: {
|
|
161
31
|
flexDirection: paginationPlacement === 'top' ? 'column-reverse' : 'column',
|
|
@@ -186,17 +186,42 @@
|
|
|
186
186
|
text-align: center;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
.selectionCell
|
|
189
|
+
.headerCell.selectionCell,
|
|
190
|
+
.cell.selectionCell {
|
|
190
191
|
overflow: visible !important;
|
|
191
192
|
display: flex;
|
|
192
|
-
align-items:
|
|
193
|
-
justify-content:
|
|
193
|
+
align-items: center;
|
|
194
|
+
justify-content: center;
|
|
194
195
|
min-width: 0;
|
|
196
|
+
padding-inline: 0;
|
|
197
|
+
padding-block: 0;
|
|
198
|
+
cursor: pointer;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.headerCell.selectionCell:hover button,
|
|
202
|
+
.cell.selectionCell:hover button {
|
|
203
|
+
border-color: var(--color-fg-default);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.headerCell.selectionCell:focus-within > button,
|
|
207
|
+
.cell.selectionCell:focus-within > button {
|
|
208
|
+
border-color: var(--color-fg-default);
|
|
195
209
|
}
|
|
196
210
|
|
|
197
|
-
.
|
|
211
|
+
.selectionHitArea {
|
|
212
|
+
display: inline-flex;
|
|
198
213
|
align-items: center;
|
|
214
|
+
justify-content: center;
|
|
215
|
+
inline-size: 100%;
|
|
216
|
+
block-size: 100%;
|
|
217
|
+
min-block-size: var(--component-size-md);
|
|
218
|
+
padding: 4px;
|
|
199
219
|
}
|
|
220
|
+
|
|
221
|
+
.sm .selectionHitArea {
|
|
222
|
+
min-block-size: var(--component-size-sm);
|
|
223
|
+
}
|
|
224
|
+
|
|
200
225
|
.clickableRow {
|
|
201
226
|
cursor: pointer;
|
|
202
227
|
}
|
|
@@ -362,11 +387,18 @@
|
|
|
362
387
|
--row-rail-offset: calc(var(--row-rail-width) + var(--row-rail-gap));
|
|
363
388
|
--row-rail-inset-block: 1px;
|
|
364
389
|
--row-rail-radius: 0 2px 2px 0;
|
|
390
|
+
--selection-rail-compensation: calc(var(--row-rail-offset) / 2);
|
|
365
391
|
}
|
|
366
392
|
|
|
367
|
-
.severityTable .
|
|
393
|
+
.severityTable .headerCell.selectionCell,
|
|
368
394
|
.severityTable .row .selectionCell {
|
|
369
|
-
padding-inline-start:
|
|
395
|
+
padding-inline-start: 0 !important;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
.severityTable .headerCell.selectionCell .selectionHitArea,
|
|
399
|
+
.severityTable .row .selectionCell .selectionHitArea {
|
|
400
|
+
inline-size: calc(100% - var(--selection-rail-compensation));
|
|
401
|
+
margin-inline-start: var(--selection-rail-compensation);
|
|
370
402
|
}
|
|
371
403
|
|
|
372
404
|
.severityTable .row.severity {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import type { PageChangeEvent } from '../../components/pagination/Pagination';
|
|
3
|
+
import type { Severity } from '../../constants/severity.types';
|
|
4
|
+
import type { ViewMode } from '../../hooks/useTableSettings';
|
|
5
|
+
export interface ColumnItem<T> {
|
|
6
|
+
id: string;
|
|
7
|
+
header: string | (() => ReactNode);
|
|
8
|
+
accessor?: keyof T;
|
|
9
|
+
sortable?: boolean;
|
|
10
|
+
sortFunction?: (a: T, b: T) => -1 | 0 | 1;
|
|
11
|
+
render?: (item: T) => ReactNode;
|
|
12
|
+
hidden?: boolean;
|
|
13
|
+
align?: 'left' | 'right' | 'center';
|
|
14
|
+
verticalAlign?: 'top' | 'middle' | 'bottom';
|
|
15
|
+
divider?: 'right' | 'left';
|
|
16
|
+
allowWrap?: boolean;
|
|
17
|
+
emptyPlaceholder?: ReactNode;
|
|
18
|
+
canHide?: boolean;
|
|
19
|
+
severity?: any;
|
|
20
|
+
}
|
|
21
|
+
export type HeaderExtrasArgs<T> = {
|
|
22
|
+
column: ColumnItem<T>;
|
|
23
|
+
index: number;
|
|
24
|
+
};
|
|
25
|
+
export type TableVariant = 'primary' | 'embedded';
|
|
26
|
+
export type SortDirection = 'asc' | 'desc' | null;
|
|
27
|
+
export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTMLDivElement>, 'onClick' | 'onMouseEnter'> & {
|
|
28
|
+
data: T[];
|
|
29
|
+
dataKey: keyof T;
|
|
30
|
+
columns: ColumnItem<T>[];
|
|
31
|
+
selectedRows?: Set<number | string>;
|
|
32
|
+
selectionMode?: 'single' | 'multiple';
|
|
33
|
+
allRowsSelected?: boolean;
|
|
34
|
+
sortById?: string;
|
|
35
|
+
sortDirection?: SortDirection;
|
|
36
|
+
loading?: boolean;
|
|
37
|
+
emptyConfig?: any;
|
|
38
|
+
variant?: TableVariant;
|
|
39
|
+
size?: 'sm' | 'md';
|
|
40
|
+
viewMode?: ViewMode;
|
|
41
|
+
striped?: boolean;
|
|
42
|
+
fillViewport?: boolean;
|
|
43
|
+
gridTemplateColumns?: string;
|
|
44
|
+
toolbar?: ReactNode;
|
|
45
|
+
headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
|
|
46
|
+
take?: number;
|
|
47
|
+
skip?: number;
|
|
48
|
+
totalItemsCount?: number;
|
|
49
|
+
paginationPlacement?: 'top' | 'bottom';
|
|
50
|
+
showFirstLast?: boolean;
|
|
51
|
+
getRowSeverity?: (row: T) => Severity | undefined;
|
|
52
|
+
onRowClick?: (row: T) => void;
|
|
53
|
+
onRowMouseEnter?: (row: T) => void;
|
|
54
|
+
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
55
|
+
onSelectAllRows?: (isSelected: boolean) => void;
|
|
56
|
+
onSortChange?: (column: ColumnItem<T>, direction: SortDirection) => void;
|
|
57
|
+
onPageChange?: (e: PageChangeEvent) => void;
|
|
58
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ColumnDef, type SortingState } from '@tanstack/react-table';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { TableProps, TableVariant } from './Table.types';
|
|
4
4
|
import { ViewMode } from '../../hooks/useTableSettings';
|
|
5
5
|
type Filterable<T> = Array<keyof T>;
|
|
6
6
|
export type TanstackTableProps<T extends Record<string, any>> = Omit<TableProps<T>, 'columns' | 'onSortChange' | 'sortById' | 'sortDirection' | 'headerExtras' | 'gridTemplateColumns' | 'toolbar'> & {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import type { ViewMode } from '../../../hooks/useTableSettings';
|
|
3
|
+
import type { ColumnItem } from '../Table.types';
|
|
4
|
+
type Props<T extends Record<string, any>> = {
|
|
5
|
+
data: T[];
|
|
6
|
+
dataKey: keyof T;
|
|
7
|
+
columns: ColumnItem<T>[];
|
|
8
|
+
gridStyle: CSSProperties;
|
|
9
|
+
striped?: boolean;
|
|
10
|
+
selectedRows?: Set<number | string>;
|
|
11
|
+
hasSelection: boolean;
|
|
12
|
+
viewMode?: ViewMode;
|
|
13
|
+
getRowSeverity?: (row: T) => any;
|
|
14
|
+
onRowClick?: (row: T) => void;
|
|
15
|
+
onRowMouseEnter?: (row: T) => void;
|
|
16
|
+
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
17
|
+
};
|
|
18
|
+
export declare function TableBody<T extends Record<string, any>>({ data, dataKey, columns, gridStyle, striped, selectedRows, hasSelection, viewMode, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, }: Props<T>): ReactNode;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cx } from '../table.classes';
|
|
3
|
+
import styles from '../Table.module.css';
|
|
4
|
+
import { TableRow } from './TableRow';
|
|
5
|
+
export function TableBody({ data, dataKey, columns, gridStyle, striped, selectedRows, hasSelection, viewMode, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, }) {
|
|
6
|
+
return (_jsx("div", { className: cx(styles.body, striped && styles.striped), role: "rowgroup", children: data.map(row => {
|
|
7
|
+
const rowId = row[dataKey];
|
|
8
|
+
return (_jsx(TableRow, { row: row, rowId: rowId, columns: columns, gridStyle: gridStyle, selectedRows: selectedRows, hasSelection: hasSelection, viewMode: viewMode, getRowSeverity: getRowSeverity, onRowClick: onRowClick, onRowMouseEnter: onRowMouseEnter, onRowSelect: onRowSelect }, `gridRow-${rowId}`));
|
|
9
|
+
}) }));
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
type Props = {
|
|
3
|
+
align?: 'left' | 'right' | 'center';
|
|
4
|
+
divider?: 'left' | 'right';
|
|
5
|
+
allowWrap?: boolean;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
export declare function TableCell({ align, divider, allowWrap, children }: Props): ReactNode;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cx } from '../table.classes';
|
|
3
|
+
import styles from '../Table.module.css';
|
|
4
|
+
export function TableCell({ align = 'left', divider, allowWrap, children }) {
|
|
5
|
+
const dividerClass = divider === 'left' ? styles.dividerLeft : divider === 'right' ? styles.dividerRight : '';
|
|
6
|
+
return (_jsx("div", { className: cx(styles.cell, allowWrap ? styles.allowWrap : styles.nowrap, dividerClass), role: "cell", "data-align": align, "data-divider": divider, children: _jsx("div", { className: styles.cellContent, children: allowWrap ? children : _jsx("div", { className: styles.cellValueEllipsis, children: children }) }) }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
import type { ColumnItem, HeaderExtrasArgs, SortDirection } from '../Table.types';
|
|
3
|
+
type Props<T> = {
|
|
4
|
+
columns: ColumnItem<T>[];
|
|
5
|
+
gridStyle: CSSProperties;
|
|
6
|
+
hasSelection: boolean;
|
|
7
|
+
selectionMode: 'single' | 'multiple';
|
|
8
|
+
allRowsSelected?: boolean;
|
|
9
|
+
onSelectAllRows?: (isSelected: boolean) => void;
|
|
10
|
+
sortById?: string;
|
|
11
|
+
sortDirection?: SortDirection;
|
|
12
|
+
onSortChange?: (column: ColumnItem<T>, direction: SortDirection) => void;
|
|
13
|
+
headerExtras?: (args: HeaderExtrasArgs<T>) => ReactNode;
|
|
14
|
+
};
|
|
15
|
+
export declare function TableHeader<T>({ columns, gridStyle, hasSelection, selectionMode, allRowsSelected, onSelectAllRows, sortById, sortDirection, onSortChange, headerExtras, }: Props<T>): React.ReactNode;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TableHeaderCell } from './TableHeaderCell';
|
|
3
|
+
import { TableSelectionCell } from './TableSelectionCell';
|
|
4
|
+
import styles from '../Table.module.css';
|
|
5
|
+
export function TableHeader({ columns, gridStyle, hasSelection, selectionMode, allRowsSelected, onSelectAllRows, sortById, sortDirection, onSortChange, headerExtras, }) {
|
|
6
|
+
return (_jsxs("div", { className: styles.headerRow, style: gridStyle, role: "row", children: [hasSelection ? (_jsx(TableSelectionCell, { isHeader: true, multiple: selectionMode === 'multiple', checked: allRowsSelected, onToggle: checked => onSelectAllRows === null || onSelectAllRows === void 0 ? void 0 : onSelectAllRows(checked) })) : null, columns.map((column, index) => (_jsx(TableHeaderCell, { column: column, index: index, sortById: sortById, sortDirection: sortDirection, onSortChange: onSortChange, extraContent: headerExtras === null || headerExtras === void 0 ? void 0 : headerExtras({ column, index }) }, column.id)))] }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ColumnItem, SortDirection } from '../Table.types';
|
|
3
|
+
type Props<T> = {
|
|
4
|
+
column: ColumnItem<T>;
|
|
5
|
+
index: number;
|
|
6
|
+
sortById?: string;
|
|
7
|
+
sortDirection?: SortDirection;
|
|
8
|
+
onSortChange?: (column: ColumnItem<T>, direction: SortDirection) => void;
|
|
9
|
+
extraContent?: ReactNode;
|
|
10
|
+
};
|
|
11
|
+
export declare function TableHeaderCell<T>({ column, index, sortById, sortDirection, onSortChange, extraContent, }: Props<T>): ReactNode;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ArrowDown, ArrowUp } from 'lucide-react';
|
|
3
|
+
import { cx, getAlignValue, getDividerClass, getHeaderAlignClasses } from '../table.classes';
|
|
4
|
+
import styles from '../Table.module.css';
|
|
5
|
+
import { getAriaSort, getHeaderLabel, getNextSortDirection, isActiveSort, shouldToggleOnKey, } from '../table.utils';
|
|
6
|
+
export function TableHeaderCell({ column, index, sortById, sortDirection, onSortChange, extraContent, }) {
|
|
7
|
+
const active = isActiveSort(sortById, column.id);
|
|
8
|
+
const ariaSort = getAriaSort(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
|
|
9
|
+
const align = getAlignValue(column);
|
|
10
|
+
const dividerClass = getDividerClass(column);
|
|
11
|
+
const alignClasses = getHeaderAlignClasses(align);
|
|
12
|
+
const handleToggleSort = () => {
|
|
13
|
+
if (!column.sortable || !onSortChange)
|
|
14
|
+
return;
|
|
15
|
+
const nextDirection = getNextSortDirection(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
|
|
16
|
+
onSortChange(column, nextDirection);
|
|
17
|
+
};
|
|
18
|
+
return (_jsxs("div", { className: cx(styles.headerCell, dividerClass), role: "columnheader", "aria-sort": ariaSort, "data-align": align, "data-divider": column.divider, "data-column-index": index, children: [_jsx("div", { className: alignClasses.inner, children: _jsx("div", { className: alignClasses.main, children: column.sortable ? (_jsxs("button", { type: "button", className: alignClasses.button, onClick: handleToggleSort, onKeyDown: e => {
|
|
19
|
+
if (!shouldToggleOnKey(e.key))
|
|
20
|
+
return;
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
handleToggleSort();
|
|
23
|
+
}, children: [_jsx("span", { className: alignClasses.label, children: getHeaderLabel(column.header) }), _jsxs("span", { className: styles.sortIndicator, "aria-hidden": "true", children: [active && sortDirection === 'asc' && _jsx(ArrowUp, {}), active && sortDirection === 'desc' && _jsx(ArrowDown, { className: styles.descending }), !active && _jsx(ArrowDown, { className: `${styles.descending} ${styles.inActiveSort}` })] })] })) : (_jsx("span", { className: alignClasses.label, children: getHeaderLabel(column.header) })) }) }), extraContent != null ? _jsx("div", { className: styles.thOverlayExtras, children: extraContent }) : null] }, column.id));
|
|
24
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CSSProperties, 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
|
+
gridStyle: CSSProperties;
|
|
8
|
+
};
|
|
9
|
+
export declare function TableLoadingBody<T>({ rows, columns, hasSelection, gridStyle, }: Props<T>): ReactNode;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _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
|
+
export function TableLoadingBody({ rows, columns, hasSelection, gridStyle, }) {
|
|
6
|
+
return (_jsx("div", { className: styles.body, role: "rowgroup", children: Array.from({ length: rows }).map((_, rowIndex) => (_jsxs("div", { className: styles.row, style: gridStyle, role: "row", children: [hasSelection ? (_jsx("div", { className: cx(styles.cell, styles.selectionCell), role: "cell" })) : null, columns.map(column => {
|
|
7
|
+
var _a;
|
|
8
|
+
return (_jsx("div", { className: cx(styles.cell, column.divider === 'left' && styles.dividerLeft, column.divider === 'right' && styles.dividerRight), role: "cell", "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, children: _jsx("div", { className: styles.cellContent, children: _jsx("div", { className: styles.cellValueEllipsis, children: _jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }) }) }, column.id));
|
|
9
|
+
})] }, `loading-row-${rowIndex}`))) }));
|
|
10
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { ViewMode } from '../../../hooks/useTableSettings';
|
|
4
|
+
import type { ColumnItem } from '../Table.types';
|
|
5
|
+
type Props<T extends Record<string, any>> = {
|
|
6
|
+
row: T;
|
|
7
|
+
rowId: string | number;
|
|
8
|
+
columns: ColumnItem<T>[];
|
|
9
|
+
gridStyle: CSSProperties;
|
|
10
|
+
selectedRows?: Set<number | string>;
|
|
11
|
+
hasSelection: boolean;
|
|
12
|
+
viewMode?: ViewMode;
|
|
13
|
+
getRowSeverity?: (row: T) => any;
|
|
14
|
+
onRowClick?: (row: T) => void;
|
|
15
|
+
onRowMouseEnter?: (row: T) => void;
|
|
16
|
+
onRowSelect?: (rowId: number | string, isSelected: boolean) => void;
|
|
17
|
+
};
|
|
18
|
+
export declare function TableRow<T extends Record<string, any>>({ row, rowId, columns, gridStyle, selectedRows, hasSelection, viewMode, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, }: Props<T>): React.ReactNode;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Checkbox } from '../../../components/forms/checkbox/Checkbox';
|
|
3
|
+
import { SeverityBgColor } from '../../../constants/severity';
|
|
4
|
+
import { useTableRowInteractions } from '../hooks/useTableRowInteractions';
|
|
5
|
+
import { cx } from '../table.classes';
|
|
6
|
+
import styles from '../Table.module.css';
|
|
7
|
+
import { getCellDisplayValue, shouldAllowWrap } from '../table.utils';
|
|
8
|
+
export function TableRow({ row, rowId, columns, gridStyle, selectedRows, hasSelection, viewMode, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, }) {
|
|
9
|
+
var _a;
|
|
10
|
+
const isSelected = (_a = selectedRows === null || selectedRows === void 0 ? void 0 : selectedRows.has(rowId)) !== null && _a !== void 0 ? _a : false;
|
|
11
|
+
const rowSeverity = getRowSeverity === null || getRowSeverity === void 0 ? void 0 : getRowSeverity(row);
|
|
12
|
+
const canSelect = Boolean(selectedRows && onRowSelect);
|
|
13
|
+
const { handleRowClick, handleRowKeyDown } = useTableRowInteractions({
|
|
14
|
+
row,
|
|
15
|
+
rowId,
|
|
16
|
+
isSelected,
|
|
17
|
+
canSelect,
|
|
18
|
+
onRowClick,
|
|
19
|
+
onRowSelect,
|
|
20
|
+
});
|
|
21
|
+
return (_jsxs("div", { className: cx(styles.row, onRowClick && styles.clickableRow, isSelected && styles.selectedRow, rowSeverity && styles.severity), style: {
|
|
22
|
+
...gridStyle,
|
|
23
|
+
['--row-severity-color']: rowSeverity
|
|
24
|
+
? SeverityBgColor[rowSeverity]
|
|
25
|
+
: undefined,
|
|
26
|
+
}, role: "row", tabIndex: onRowClick ? 0 : -1, onKeyDown: handleRowKeyDown, onMouseEnter: () => onRowMouseEnter === null || onRowMouseEnter === void 0 ? void 0 : onRowMouseEnter(row), onClick: handleRowClick, children: [hasSelection ? (_jsx("div", { className: cx(styles.cell, styles.selectionCell), role: "cell", onClick: e => {
|
|
27
|
+
e.stopPropagation();
|
|
28
|
+
onRowSelect === null || onRowSelect === void 0 ? void 0 : onRowSelect(rowId, !isSelected);
|
|
29
|
+
}, children: _jsx("div", { className: styles.selectionHitArea, children: _jsx(Checkbox, { variant: "primary", checked: isSelected, size: "sm", onChange: (checked, e) => {
|
|
30
|
+
e.stopPropagation();
|
|
31
|
+
onRowSelect === null || onRowSelect === void 0 ? void 0 : onRowSelect(rowId, checked);
|
|
32
|
+
} }) }) })) : null, columns.map(column => {
|
|
33
|
+
var _a;
|
|
34
|
+
const allowWrap = shouldAllowWrap(column.allowWrap, isSelected, viewMode);
|
|
35
|
+
const cellValue = getCellDisplayValue(row, column);
|
|
36
|
+
return (_jsx("div", { className: cx(styles.cell, allowWrap ? styles.allowWrap : styles.nowrap, column.divider === 'left' && styles.dividerLeft, column.divider === 'right' && styles.dividerRight), role: "cell", "data-align": (_a = column.align) !== null && _a !== void 0 ? _a : 'left', "data-divider": column.divider, children: _jsx("div", { className: styles.cellContent, children: allowWrap ? cellValue : _jsx("div", { className: styles.cellValueEllipsis, children: cellValue }) }) }, column.id));
|
|
37
|
+
})] }));
|
|
38
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React, { type JSX } from 'react';
|
|
2
|
+
type Props = {
|
|
3
|
+
checked?: boolean;
|
|
4
|
+
isHeader?: boolean;
|
|
5
|
+
multiple?: boolean;
|
|
6
|
+
onToggle: (checked: boolean, e: React.MouseEvent | React.KeyboardEvent | any) => void;
|
|
7
|
+
};
|
|
8
|
+
export declare function TableSelectionCell({ checked, isHeader, multiple, onToggle }: Props): JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Checkbox } from '../../../components/forms/checkbox/Checkbox';
|
|
3
|
+
import { cx } from '../table.classes';
|
|
4
|
+
import styles from '../Table.module.css';
|
|
5
|
+
export function TableSelectionCell({ checked, isHeader, multiple, onToggle }) {
|
|
6
|
+
return (_jsx("div", { className: cx(styles.headerCell, styles.selectionCell), role: isHeader ? 'columnheader' : 'cell', onClick: e => {
|
|
7
|
+
if (isHeader && !multiple)
|
|
8
|
+
return;
|
|
9
|
+
e.stopPropagation();
|
|
10
|
+
onToggle(!checked, e);
|
|
11
|
+
}, children: isHeader && !multiple ? null : (_jsx("div", { className: styles.selectionHitArea, children: _jsx(Checkbox, { size: "sm", variant: "primary", checked: checked, onChange: (nextChecked, e) => {
|
|
12
|
+
e.stopPropagation();
|
|
13
|
+
onToggle(nextChecked, e);
|
|
14
|
+
} }) })) }));
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { KeyboardEvent, MouseEvent } from 'react';
|
|
2
|
+
type UseTableRowInteractionsArgs<T> = {
|
|
3
|
+
row: T;
|
|
4
|
+
rowId: string | number;
|
|
5
|
+
isSelected: boolean;
|
|
6
|
+
canSelect: boolean;
|
|
7
|
+
onRowClick?: (row: T) => void;
|
|
8
|
+
onRowSelect?: (rowId: string | number, isSelected: boolean) => void;
|
|
9
|
+
};
|
|
10
|
+
type UseTableRowInteractionsReturn = {
|
|
11
|
+
handleRowClick: (e: MouseEvent<HTMLDivElement>) => void;
|
|
12
|
+
handleRowKeyDown: (e: KeyboardEvent<HTMLDivElement>) => void;
|
|
13
|
+
};
|
|
14
|
+
export declare function useTableRowInteractions<T>({ row, rowId, isSelected, canSelect, onRowClick, onRowSelect, }: UseTableRowInteractionsArgs<T>): UseTableRowInteractionsReturn;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
import { isModifierClick, shouldToggleOnKey } from '../table.utils';
|
|
3
|
+
export function useTableRowInteractions({ row, rowId, isSelected, canSelect, onRowClick, onRowSelect, }) {
|
|
4
|
+
const handleRowClick = useCallback((e) => {
|
|
5
|
+
if (isModifierClick(e) && canSelect) {
|
|
6
|
+
e.preventDefault();
|
|
7
|
+
e.stopPropagation();
|
|
8
|
+
onRowSelect === null || onRowSelect === void 0 ? void 0 : onRowSelect(rowId, !isSelected);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row);
|
|
12
|
+
}, [canSelect, isSelected, onRowClick, onRowSelect, row, rowId]);
|
|
13
|
+
const handleRowKeyDown = useCallback((e) => {
|
|
14
|
+
if (!onRowClick)
|
|
15
|
+
return;
|
|
16
|
+
if (!shouldToggleOnKey(e.key))
|
|
17
|
+
return;
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
onRowClick(row);
|
|
20
|
+
}, [onRowClick, row]);
|
|
21
|
+
return {
|
|
22
|
+
handleRowClick,
|
|
23
|
+
handleRowKeyDown,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ColumnItem } from './Table.types';
|
|
2
|
+
export declare function cx(...values: Array<string | false | null | undefined>): string;
|
|
3
|
+
export declare function getDividerClass<T>(column: ColumnItem<T>): string;
|
|
4
|
+
export declare function getAlignValue<T>(column: ColumnItem<T>): 'left' | 'right' | 'center';
|
|
5
|
+
export declare function getHeaderAlignClasses(align: 'left' | 'right' | 'center'): {
|
|
6
|
+
inner: string;
|
|
7
|
+
main: string;
|
|
8
|
+
button: string;
|
|
9
|
+
label: string;
|
|
10
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import styles from './Table.module.css';
|
|
2
|
+
export function cx(...values) {
|
|
3
|
+
return values.filter(Boolean).join(' ');
|
|
4
|
+
}
|
|
5
|
+
export function getDividerClass(column) {
|
|
6
|
+
if (column.divider === 'left')
|
|
7
|
+
return styles.dividerLeft;
|
|
8
|
+
if (column.divider === 'right')
|
|
9
|
+
return styles.dividerRight;
|
|
10
|
+
return '';
|
|
11
|
+
}
|
|
12
|
+
export function getAlignValue(column) {
|
|
13
|
+
var _a;
|
|
14
|
+
return (_a = column.align) !== null && _a !== void 0 ? _a : 'left';
|
|
15
|
+
}
|
|
16
|
+
export function getHeaderAlignClasses(align) {
|
|
17
|
+
return {
|
|
18
|
+
inner: cx(styles.thInner, align === 'right' && styles.thInnerRight, align === 'center' && styles.thInnerCenter),
|
|
19
|
+
main: cx(styles.thMain, align === 'right' && styles.thMainRight, align === 'center' && styles.thMainCenter),
|
|
20
|
+
button: cx(styles.thButton, align === 'right' && styles.thButtonRight, align === 'center' && styles.thButtonCenter),
|
|
21
|
+
label: cx(styles.thLabel, align === 'right' && styles.thLabelRight, align === 'center' && styles.thLabelCenter),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ColumnItem } from './Table';
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ColumnItem } from './Table.types';
|
|
3
|
+
export declare const SELECTION_COLUMN_PX: 40;
|
|
3
4
|
export type SortDirection = 'asc' | 'desc' | null;
|
|
4
5
|
export declare function getVisibleColumns<T>(columns: Array<ColumnItem<T>>): Array<ColumnItem<T>>;
|
|
5
|
-
export declare function getColumnStyle(columnId: string, columnStyles: Partial<Record<string, CSSProperties>> | undefined, alignment?: 'left' | 'right' | 'center', verticalAlignment?: 'top' | 'middle' | 'bottom', divider?: boolean): CSSProperties;
|
|
6
6
|
export declare function getHeaderLabel(header: string | (() => ReactNode)): ReactNode;
|
|
7
7
|
export declare function isActiveSort(sortById: string | undefined, columnId: string): boolean;
|
|
8
8
|
export declare function getAriaSort(sortable: boolean | undefined, active: boolean, direction: SortDirection): 'ascending' | 'descending' | 'none';
|
|
@@ -14,4 +14,7 @@ export declare function isModifierClick(e: {
|
|
|
14
14
|
}): boolean;
|
|
15
15
|
export declare function shouldAllowWrap(columnAllowWrap: boolean | undefined, isRowSelected: boolean, viewMode?: 'wrapped' | string): boolean;
|
|
16
16
|
export declare function getCellDisplayValue<T extends Record<string, any>>(row: T, column: ColumnItem<T>): ReactNode;
|
|
17
|
-
export declare function
|
|
17
|
+
export declare function buildDefaultGridTemplate(args: {
|
|
18
|
+
hasSelection: boolean;
|
|
19
|
+
colCount: number;
|
|
20
|
+
}): string;
|
|
@@ -1,15 +1,6 @@
|
|
|
1
|
+
export const SELECTION_COLUMN_PX = 40;
|
|
1
2
|
export function getVisibleColumns(columns) {
|
|
2
|
-
return columns.filter(
|
|
3
|
-
}
|
|
4
|
-
export function getColumnStyle(columnId, columnStyles, alignment, verticalAlignment, divider) {
|
|
5
|
-
const baseStyle = columnStyles === null || columnStyles === void 0 ? void 0 : columnStyles[columnId];
|
|
6
|
-
return {
|
|
7
|
-
...(baseStyle !== null && baseStyle !== void 0 ? baseStyle : {}),
|
|
8
|
-
...(alignment === 'right' ? { fontVariantNumeric: 'tabular-nums' } : null),
|
|
9
|
-
verticalAlign: verticalAlignment !== null && verticalAlignment !== void 0 ? verticalAlignment : 'top',
|
|
10
|
-
textAlign: alignment !== null && alignment !== void 0 ? alignment : 'left',
|
|
11
|
-
...(divider ? { borderLeft: '1px solid var(--color-border-subtle)' } : null),
|
|
12
|
-
};
|
|
3
|
+
return columns.filter(column => !column.hidden);
|
|
13
4
|
}
|
|
14
5
|
export function getHeaderLabel(header) {
|
|
15
6
|
return typeof header === 'function' ? header() : header;
|
|
@@ -18,9 +9,7 @@ export function isActiveSort(sortById, columnId) {
|
|
|
18
9
|
return sortById === columnId;
|
|
19
10
|
}
|
|
20
11
|
export function getAriaSort(sortable, active, direction) {
|
|
21
|
-
if (!sortable)
|
|
22
|
-
return 'none';
|
|
23
|
-
if (!active)
|
|
12
|
+
if (!sortable || !active || !direction)
|
|
24
13
|
return 'none';
|
|
25
14
|
return direction === 'asc' ? 'ascending' : 'descending';
|
|
26
15
|
}
|
|
@@ -47,14 +36,19 @@ export function getCellDisplayValue(row, column) {
|
|
|
47
36
|
const empty = (_a = column.emptyPlaceholder) !== null && _a !== void 0 ? _a : '';
|
|
48
37
|
if (column.render) {
|
|
49
38
|
const rendered = column.render(row);
|
|
50
|
-
return rendered
|
|
39
|
+
return rendered !== null && rendered !== void 0 ? rendered : empty;
|
|
51
40
|
}
|
|
52
41
|
if (column.accessor) {
|
|
53
42
|
const value = row[column.accessor];
|
|
54
|
-
return value
|
|
43
|
+
return value !== null && value !== void 0 ? value : empty;
|
|
55
44
|
}
|
|
56
|
-
return
|
|
57
|
-
}
|
|
58
|
-
export function
|
|
59
|
-
|
|
45
|
+
return empty;
|
|
46
|
+
}
|
|
47
|
+
export function buildDefaultGridTemplate(args) {
|
|
48
|
+
const parts = [];
|
|
49
|
+
if (args.hasSelection)
|
|
50
|
+
parts.push(`${SELECTION_COLUMN_PX}px`);
|
|
51
|
+
for (let i = 0; i < args.colCount; i++)
|
|
52
|
+
parts.push('minmax(120px, 1fr)');
|
|
53
|
+
return parts.join(' ');
|
|
60
54
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ColumnDef, ColumnSizingState, SortingState, VisibilityState } from '@tanstack/react-table';
|
|
2
|
-
import
|
|
2
|
+
import { ColumnItem } from './Table.types';
|
|
3
3
|
type AnyRecord = Record<string, any>;
|
|
4
4
|
export declare function getColumnId<T>(def: ColumnDef<T, any>, index: number): string;
|
|
5
5
|
export declare function buildColumnVisibilityFromVisibleIds<T>(defs: ReadonlyArray<ColumnDef<T, any>>, visibleColumnIds?: string[]): VisibilityState;
|
|
@@ -14,7 +14,6 @@ export declare function buildDistributedGridTemplateColumns(args: {
|
|
|
14
14
|
table: any;
|
|
15
15
|
allowedIds: Set<string>;
|
|
16
16
|
hasSelection: boolean;
|
|
17
|
-
selectionPx: number;
|
|
18
17
|
defaultMinPx: number;
|
|
19
18
|
columnSizing: ColumnSizingState;
|
|
20
19
|
}): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SELECTION_COLUMN_PX } from './table.utils';
|
|
1
2
|
export function getColumnId(def, index) {
|
|
2
3
|
const d = def;
|
|
3
4
|
if (d.id != null && String(d.id).length > 0)
|
|
@@ -92,11 +93,11 @@ function clamp(value, min, max) {
|
|
|
92
93
|
}
|
|
93
94
|
export function buildDistributedGridTemplateColumns(args) {
|
|
94
95
|
var _a, _b, _c, _d;
|
|
95
|
-
const { table, allowedIds, hasSelection,
|
|
96
|
+
const { table, allowedIds, hasSelection, defaultMinPx, columnSizing } = args;
|
|
96
97
|
const parts = [];
|
|
97
98
|
const leaf = table.getVisibleLeafColumns().filter((c) => allowedIds.has(c.id));
|
|
98
99
|
if (hasSelection)
|
|
99
|
-
parts.push(`${
|
|
100
|
+
parts.push(`${SELECTION_COLUMN_PX}px`);
|
|
100
101
|
for (const c of leaf) {
|
|
101
102
|
const def = c.columnDef;
|
|
102
103
|
const meta = ((_b = ((_a = def.meta) !== null && _a !== void 0 ? _a : {})) !== null && _b !== void 0 ? _b : {});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Examples:
|
|
6
6
|
* - formatDate(new Date(), { userFriendlyLabel: true }) => "I dag"
|
|
7
7
|
* - formatDate(new Date(), { userFriendlyLabel: true, showTime: true }) => "I dag, kl. 14:30"
|
|
8
|
-
* - formatDate(date, { showTime: true }) => "10
|
|
8
|
+
* - formatDate(date, { showTime: true }) => "10.03.2026 14:30"
|
|
9
9
|
*
|
|
10
10
|
* @param date - The Date or date-parsable value to format
|
|
11
11
|
* @param options.showTime - If true, append time "hh:mm" or "hh:mm:ss"
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Examples:
|
|
6
6
|
* - formatDate(new Date(), { userFriendlyLabel: true }) => "I dag"
|
|
7
7
|
* - formatDate(new Date(), { userFriendlyLabel: true, showTime: true }) => "I dag, kl. 14:30"
|
|
8
|
-
* - formatDate(date, { showTime: true }) => "10
|
|
8
|
+
* - formatDate(date, { showTime: true }) => "10.03.2026 14:30"
|
|
9
9
|
*
|
|
10
10
|
* @param date - The Date or date-parsable value to format
|
|
11
11
|
* @param options.showTime - If true, append time "hh:mm" or "hh:mm:ss"
|
|
@@ -44,7 +44,7 @@ export function formatDate(date, options = {}) {
|
|
|
44
44
|
const day = pad(d.getDate());
|
|
45
45
|
const month = pad(d.getMonth() + 1);
|
|
46
46
|
const year = d.getFullYear();
|
|
47
|
-
const base = `${day}
|
|
47
|
+
const base = `${day}.${month}.${year}`;
|
|
48
48
|
if (!showTime)
|
|
49
49
|
return base;
|
|
50
50
|
return `${base} ${formatTime()}`;
|