@neasg/design-system 0.4.11 → 0.4.12
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/avatar-profile-popover.d.ts +34 -0
- package/dist/avatar-profile-popover.js +27 -0
- package/dist/badge.d.ts +1 -1
- package/dist/button.d.ts +1 -1
- package/dist/card.d.ts +2 -0
- package/dist/card.js +72 -3
- package/dist/command-search.d.ts +47 -2
- package/dist/command-search.js +173 -24
- package/dist/command.d.ts +2 -0
- package/dist/command.js +2 -2
- package/dist/dialog-primitive.js +1 -1
- package/dist/draggable-tabs.d.ts +3 -0
- package/dist/draggable-tabs.js +4 -0
- package/dist/editable-table.js +2 -2
- package/dist/guidance-tip.d.ts +26 -0
- package/dist/guidance-tip.js +162 -0
- package/dist/index.d.ts +13 -5
- package/dist/index.js +5 -1
- package/dist/jump-target-highlight.d.ts +13 -0
- package/dist/jump-target-highlight.js +95 -0
- package/dist/layout.d.ts +27 -5
- package/dist/layout.js +128 -34
- package/dist/message-item.js +9 -10
- package/dist/notification.js +1 -1
- package/dist/page-layout.d.ts +22 -0
- package/dist/page-layout.js +38 -0
- package/dist/page-section.js +1 -1
- package/dist/popover-menu.js +2 -2
- package/dist/routing-timeline.js +1 -1
- package/dist/table-column-visibility.d.ts +2 -1
- package/dist/table-column-visibility.js +9 -8
- package/dist/table-toolbar.d.ts +2 -1
- package/dist/table-toolbar.js +7 -2
- package/dist/table.d.ts +31 -2
- package/dist/table.js +298 -23
- package/dist/tabs.d.ts +2 -1
- package/dist/tabs.js +8 -5
- package/dist/theme-switcher.d.ts +1 -1
- package/dist/theme-switcher.js +4 -6
- package/package.json +1 -1
|
@@ -13,10 +13,11 @@ export interface TableColumnVisibilityMenuProps<Row> extends PopoverPlacementPro
|
|
|
13
13
|
triggerClassName?: string;
|
|
14
14
|
contentClassName?: string;
|
|
15
15
|
className?: string;
|
|
16
|
+
title?: React.ReactNode;
|
|
16
17
|
searchPlaceholder?: string;
|
|
17
18
|
restoreDefaultsLabel?: string;
|
|
18
19
|
emptyMessage?: React.ReactNode;
|
|
19
20
|
minVisibleColumns?: number;
|
|
20
21
|
}
|
|
21
|
-
declare function TableColumnVisibilityMenu<Row>({ columns, visibleColumnKeys, onVisibleColumnKeysChange, defaultVisibleColumnKeys, trigger, triggerLabel, triggerClassName, contentClassName, className, searchPlaceholder, restoreDefaultsLabel, emptyMessage, minVisibleColumns, align, sideOffset, side, }: TableColumnVisibilityMenuProps<Row>): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
declare function TableColumnVisibilityMenu<Row>({ columns, visibleColumnKeys, onVisibleColumnKeysChange, defaultVisibleColumnKeys, trigger, triggerLabel, triggerClassName, contentClassName, className, title, searchPlaceholder, restoreDefaultsLabel, emptyMessage, minVisibleColumns, align, sideOffset, side, }: TableColumnVisibilityMenuProps<Row>): import("react/jsx-runtime").JSX.Element;
|
|
22
23
|
export { TableColumnVisibilityMenu };
|
|
@@ -10,7 +10,7 @@ import { Checkbox } from "./checkbox";
|
|
|
10
10
|
import { InputControl } from "./input-control";
|
|
11
11
|
import { cn } from "./lib/utils";
|
|
12
12
|
import { Popover } from "./popover";
|
|
13
|
-
import { PopoverMenuFooter, PopoverMenuFooterAction, PopoverMenuFooterMeta, } from "./popover-menu";
|
|
13
|
+
import { PopoverMenuFooter, PopoverMenuFooterAction, PopoverMenuFooterMeta, PopoverMenuGroupLabel, } from "./popover-menu";
|
|
14
14
|
import { SearchInputShell } from "./search-input-shell";
|
|
15
15
|
function getColumnVisibilityLabel(column) {
|
|
16
16
|
if (column.visibilityLabel) {
|
|
@@ -52,7 +52,7 @@ function SortableColumnOption({ columnKey, label, checked, disabled, onToggle, }
|
|
|
52
52
|
? "cursor-grab active:cursor-grabbing"
|
|
53
53
|
: "cursor-not-allowed opacity-40"), ...(checked ? { ...attributes, ...listeners } : {}), children: _jsx(GripVertical, { className: "h-4 w-4", "aria-hidden": "true" }) }), _jsx(Checkbox, { id: checkboxId, checked: checked, disabled: disabled, onChange: onToggle, "aria-label": label }), _jsx("label", { htmlFor: checkboxId, className: cn("min-w-0 flex-1 cursor-pointer truncate", disabled && "cursor-not-allowed text-muted-foreground"), children: label })] }));
|
|
54
54
|
}
|
|
55
|
-
function TableColumnVisibilityMenu({ columns, visibleColumnKeys, onVisibleColumnKeysChange, defaultVisibleColumnKeys, trigger, triggerLabel = "Customize columns", triggerClassName, contentClassName, className, searchPlaceholder = "Search columns", restoreDefaultsLabel = "Restore defaults", emptyMessage = "No columns found", minVisibleColumns = 1, align = "end", sideOffset = 4, side, }) {
|
|
55
|
+
function TableColumnVisibilityMenu({ columns, visibleColumnKeys, onVisibleColumnKeysChange, defaultVisibleColumnKeys, trigger, triggerLabel = "Customize columns", triggerClassName, contentClassName, className, title = "Customize columns", searchPlaceholder = "Search columns", restoreDefaultsLabel = "Restore defaults", emptyMessage = "No columns found", minVisibleColumns = 1, align = "end", sideOffset = 4, side, }) {
|
|
56
56
|
const [query, setQuery] = React.useState("");
|
|
57
57
|
const sensors = useSensors(useSensor(PointerSensor, {
|
|
58
58
|
activationConstraint: {
|
|
@@ -62,6 +62,7 @@ function TableColumnVisibilityMenu({ columns, visibleColumnKeys, onVisibleColumn
|
|
|
62
62
|
coordinateGetter: sortableKeyboardCoordinates,
|
|
63
63
|
}));
|
|
64
64
|
const searchInputId = React.useId();
|
|
65
|
+
const titleId = React.useId();
|
|
65
66
|
const requiredVisibleColumns = Math.max(0, minVisibleColumns);
|
|
66
67
|
const selectableColumns = React.useMemo(() => columns.filter((column) => column.hideable !== false), [columns]);
|
|
67
68
|
const defaultKeys = React.useMemo(() => orderColumnKeys(columns, defaultVisibleColumnKeys !== null && defaultVisibleColumnKeys !== void 0 ? defaultVisibleColumnKeys : columns
|
|
@@ -110,11 +111,11 @@ function TableColumnVisibilityMenu({ columns, visibleColumnKeys, onVisibleColumn
|
|
|
110
111
|
commitVisibleColumnKeys(arrayMove(currentKeys, oldIndex, newIndex));
|
|
111
112
|
}, [commitVisibleColumnKeys, currentKeys]);
|
|
112
113
|
const defaultTrigger = (_jsx(Button, { type: "button", variant: "outline", size: "icon", "aria-label": triggerLabel, className: triggerClassName, children: _jsx(Columns3, { "aria-hidden": "true" }) }));
|
|
113
|
-
return (_jsx(Popover, { trigger: trigger !== null && trigger !== void 0 ? trigger : defaultTrigger, align: align, side: side, sideOffset: sideOffset, contentClassName: cn("w-80 p-0", contentClassName), children: _jsxs("div", { className: cn("flex max-h-96 flex-col", className), children: [_jsxs("div", { className: "border-b p-2", children: [_jsx("label", { htmlFor: searchInputId, className: "sr-only", children: searchPlaceholder }), _jsx(SearchInputShell, { children: _jsx(InputControl, { id: searchInputId, value: query, onChange: (event) => setQuery(event.target.value), placeholder: searchPlaceholder, className: "h-8 bg-background pl-8 pr-2" }) })] }),
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
return (_jsx(Popover, { trigger: trigger !== null && trigger !== void 0 ? trigger : defaultTrigger, align: align, side: side, sideOffset: sideOffset, contentClassName: cn("w-80 p-0", contentClassName), "aria-labelledby": title ? titleId : undefined, children: _jsxs("div", { className: cn("flex max-h-96 flex-col", className), children: [_jsxs("div", { className: "border-b p-2", children: [_jsx("label", { htmlFor: searchInputId, className: "sr-only", children: searchPlaceholder }), _jsx(SearchInputShell, { children: _jsx(InputControl, { id: searchInputId, value: query, onChange: (event) => setQuery(event.target.value), placeholder: searchPlaceholder, className: "h-8 bg-background pl-8 pr-2" }) })] }), _jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto p-1", children: [title ? (_jsx(PopoverMenuGroupLabel, { id: titleId, children: title })) : null, filteredColumns.length ? (_jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: filteredColumns.map((column) => column.key), strategy: verticalListSortingStrategy, children: filteredColumns.map((column) => {
|
|
115
|
+
const label = getColumnVisibilityLabel(column);
|
|
116
|
+
const checked = visibleColumnKeySet.has(column.key);
|
|
117
|
+
const disabled = checked && visibleColumnCount <= requiredVisibleColumns;
|
|
118
|
+
return (_jsx(SortableColumnOption, { columnKey: column.key, label: label, checked: checked, disabled: disabled, onToggle: () => toggleColumn(column.key) }, column.key));
|
|
119
|
+
}) }) })) : (_jsx("div", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: emptyMessage }))] }), _jsxs(PopoverMenuFooter, { inset: "flush", className: "justify-between", children: [_jsx(PopoverMenuFooterAction, { onClick: () => commitVisibleColumnKeys(defaultKeys), disabled: !canRestoreDefaults, className: "w-auto min-w-0 flex-1", children: restoreDefaultsLabel }), _jsxs(PopoverMenuFooterMeta, { children: [visibleColumnCount, " of ", columns.length] })] })] }) }));
|
|
119
120
|
}
|
|
120
121
|
export { TableColumnVisibilityMenu };
|
package/dist/table-toolbar.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import { type SearchInputProps } from "./search-input";
|
|
3
3
|
export interface TableToolbarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
search?: SearchInputProps;
|
|
5
|
+
actionsClassName?: string;
|
|
5
6
|
}
|
|
6
|
-
declare function TableToolbar({ search, className, children, ...props }: TableToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
declare function TableToolbar({ search, className, actionsClassName, children, ...props }: TableToolbarProps): import("react/jsx-runtime").JSX.Element;
|
|
7
8
|
export { TableToolbar };
|
package/dist/table-toolbar.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { SearchInput } from "./search-input";
|
|
3
3
|
import { cn } from "./lib/utils";
|
|
4
|
-
function TableToolbar({ search, className, children, ...props }) {
|
|
5
|
-
|
|
4
|
+
function TableToolbar({ search, className, actionsClassName, children, ...props }) {
|
|
5
|
+
const hasSearch = Boolean(search);
|
|
6
|
+
return (_jsxs("div", { className: cn(hasSearch
|
|
7
|
+
? "grid w-full grid-cols-1 items-center gap-[calc(var(--space-1)+0.125rem)] sm:grid-cols-[minmax(calc(var(--space-10)*5),28rem)_minmax(0,1fr)]"
|
|
8
|
+
: "flex w-full flex-wrap items-center justify-end gap-[calc(var(--space-1)+0.125rem)]", className), ...props, children: [search ? (_jsx(SearchInput, { ...search, containerClassName: cn("w-full min-w-[calc(var(--space-10)*5)] max-w-md", search.containerClassName) })) : null, children ? (_jsx("div", { className: cn("flex flex-wrap items-center gap-[calc(var(--space-1)+0.125rem)]", hasSearch
|
|
9
|
+
? "justify-start sm:justify-end sm:justify-self-end"
|
|
10
|
+
: "justify-end", actionsClassName), children: children })) : null] }));
|
|
6
11
|
}
|
|
7
12
|
export { TableToolbar };
|
package/dist/table.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ declare const TableRoot: React.ForwardRefExoticComponent<TableRootProps & React.
|
|
|
7
7
|
interface TableContainerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
8
|
}
|
|
9
9
|
declare const TableContainer: React.ForwardRefExoticComponent<TableContainerProps & React.RefAttributes<HTMLDivElement>>;
|
|
10
|
+
export type TableColumnWidths = Record<string, number>;
|
|
10
11
|
declare const TableHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
11
12
|
declare const TableBody: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
12
13
|
declare const TableFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
@@ -16,12 +17,16 @@ declare const TableHead: React.ForwardRefExoticComponent<React.ThHTMLAttributes<
|
|
|
16
17
|
minWidth?: string;
|
|
17
18
|
maxWidth?: string;
|
|
18
19
|
wrap?: boolean;
|
|
20
|
+
treatWidthAsMinWidth?: boolean;
|
|
21
|
+
containOverflow?: boolean;
|
|
19
22
|
} & React.RefAttributes<HTMLTableCellElement>>;
|
|
20
23
|
declare const TableCell: React.ForwardRefExoticComponent<React.TdHTMLAttributes<HTMLTableCellElement> & {
|
|
21
24
|
width?: string;
|
|
22
25
|
minWidth?: string;
|
|
23
26
|
maxWidth?: string;
|
|
24
27
|
wrap?: boolean;
|
|
28
|
+
treatWidthAsMinWidth?: boolean;
|
|
29
|
+
containOverflow?: boolean;
|
|
25
30
|
} & React.RefAttributes<HTMLTableCellElement>>;
|
|
26
31
|
declare const TableCaption: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableCaptionElement> & React.RefAttributes<HTMLTableCaptionElement>>;
|
|
27
32
|
type TableAlign = "left" | "center" | "right";
|
|
@@ -76,6 +81,12 @@ export interface TableColumn<Row> {
|
|
|
76
81
|
cellClassName?: string;
|
|
77
82
|
/** Pins the column to the left or right edge while the table scrolls horizontally. */
|
|
78
83
|
sticky?: "left" | "right";
|
|
84
|
+
/** Enables a resize handle for this column. Use `resizableColumns` on Table to opt every column in by default. */
|
|
85
|
+
resizable?: boolean;
|
|
86
|
+
/** Minimum pixel width while resizing. Defaults to `minWidth`, then 64. */
|
|
87
|
+
resizeMinWidth?: number;
|
|
88
|
+
/** Maximum pixel width while resizing. Omit to allow the column to grow. */
|
|
89
|
+
resizeMaxWidth?: number;
|
|
79
90
|
}
|
|
80
91
|
export interface TableSortingProps {
|
|
81
92
|
field: string | null;
|
|
@@ -95,8 +106,16 @@ interface SortableTableHeadProps<T extends string> {
|
|
|
95
106
|
maxWidth?: string;
|
|
96
107
|
align?: TableAlign;
|
|
97
108
|
sortLabel?: string;
|
|
109
|
+
resizeHandle?: React.ReactNode;
|
|
110
|
+
treatWidthAsMinWidth?: boolean;
|
|
111
|
+
containOverflow?: boolean;
|
|
112
|
+
}
|
|
113
|
+
declare function SortableTableHead<T extends string>({ field, children, currentSortField, currentSortDirection, onSort, className, allowWrap, width, minWidth, maxWidth, align, sortLabel, resizeHandle, treatWidthAsMinWidth, containOverflow, }: SortableTableHeadProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
114
|
+
export interface TableColumnResizeHandleRenderProps<Row> {
|
|
115
|
+
column: TableColumn<Row>;
|
|
116
|
+
nextColumn: TableColumn<Row>;
|
|
117
|
+
handle: React.ReactElement;
|
|
98
118
|
}
|
|
99
|
-
declare function SortableTableHead<T extends string>({ field, children, currentSortField, currentSortDirection, onSort, className, allowWrap, width, minWidth, maxWidth, align, sortLabel, }: SortableTableHeadProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
100
119
|
export interface TableProps<Row> extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
|
|
101
120
|
columns: TableColumn<Row>[];
|
|
102
121
|
rows: Row[];
|
|
@@ -117,10 +136,20 @@ export interface TableProps<Row> extends Omit<React.HTMLAttributes<HTMLDivElemen
|
|
|
117
136
|
loadingRows?: number;
|
|
118
137
|
/** Optional controlled ordered list of visible column keys. Omit to render every column in config order. */
|
|
119
138
|
visibleColumnKeys?: readonly string[];
|
|
139
|
+
/** When true, every column is resizable unless its column config sets `resizable: false`. */
|
|
140
|
+
resizableColumns?: boolean;
|
|
141
|
+
/** Controlled pixel widths keyed by column key. */
|
|
142
|
+
columnWidths?: TableColumnWidths;
|
|
143
|
+
/** Initial pixel widths keyed by column key for uncontrolled resizing. */
|
|
144
|
+
defaultColumnWidths?: TableColumnWidths;
|
|
145
|
+
/** Emits whenever a resize handle changes column widths. */
|
|
146
|
+
onColumnWidthsChange?: (columnWidths: TableColumnWidths) => void;
|
|
147
|
+
/** Optional hook for decorating resize handles without replacing table sizing behavior. */
|
|
148
|
+
renderColumnResizeHandle?: (props: TableColumnResizeHandleRenderProps<Row>) => React.ReactNode;
|
|
120
149
|
/** When true, applies alternating row backgrounds for easier scanning. */
|
|
121
150
|
striped?: boolean;
|
|
122
151
|
/** When set, rows become interactive: cursor-pointer, hover highlight, and click handling. */
|
|
123
152
|
onRowClick?: (row: Row, index: number) => void;
|
|
124
153
|
}
|
|
125
|
-
declare function Table<Row>({ columns, rows, getRowKey, emptyState, toolbar, caption, className, containerClassName, tableClassName, rowClassName, rowTone, maxHeight, sorting, pagination, loading, loadingRows, visibleColumnKeys, striped, onRowClick, style, ...props }: TableProps<Row>): import("react/jsx-runtime").JSX.Element;
|
|
154
|
+
declare function Table<Row>({ columns, rows, getRowKey, emptyState, toolbar, caption, className, containerClassName, tableClassName, rowClassName, rowTone, maxHeight, sorting, pagination, loading, loadingRows, visibleColumnKeys, resizableColumns, columnWidths, defaultColumnWidths, onColumnWidthsChange, renderColumnResizeHandle, striped, onRowClick, onScroll, style, ...props }: TableProps<Row>): import("react/jsx-runtime").JSX.Element;
|
|
126
155
|
export { Table, TableRoot, TableContainer, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, SortableTableHead, TableRowSkeleton, };
|
package/dist/table.js
CHANGED
|
@@ -11,8 +11,11 @@ const TableRoot = React.forwardRef(({ className, wrapperClassName: _wrapperClass
|
|
|
11
11
|
TableRoot.displayName = "TableRoot";
|
|
12
12
|
const TableContainer = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("min-h-0 overflow-auto rounded-lg border border-[hsl(var(--table-border))] bg-card text-card-foreground", className), ...props })));
|
|
13
13
|
TableContainer.displayName = "TableContainer";
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const DEFAULT_COLUMN_RESIZE_MIN_WIDTH = 64;
|
|
15
|
+
const DEFAULT_COLUMN_RESIZE_START_WIDTH = 160;
|
|
16
|
+
const COLUMN_RESIZE_KEYBOARD_STEP = 16;
|
|
17
|
+
function getTableColumnSizingStyle({ style, width, minWidth, maxWidth, treatWidthAsMinWidth = true, }) {
|
|
18
|
+
const resolvedMinWidth = minWidth !== null && minWidth !== void 0 ? minWidth : (treatWidthAsMinWidth ? width : undefined);
|
|
16
19
|
return {
|
|
17
20
|
...style,
|
|
18
21
|
...(width ? { width } : {}),
|
|
@@ -20,6 +23,94 @@ function getTableColumnSizingStyle({ style, width, minWidth, maxWidth, }) {
|
|
|
20
23
|
...(maxWidth ? { maxWidth } : {}),
|
|
21
24
|
};
|
|
22
25
|
}
|
|
26
|
+
function overflowContainmentClassName({ containOverflow, wrap, }) {
|
|
27
|
+
if (!containOverflow) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return wrap
|
|
31
|
+
? "break-words [overflow-wrap:anywhere]"
|
|
32
|
+
: "overflow-hidden text-ellipsis";
|
|
33
|
+
}
|
|
34
|
+
function parsePixelSize(value) {
|
|
35
|
+
if (typeof value === "number") {
|
|
36
|
+
return Number.isFinite(value) ? value : undefined;
|
|
37
|
+
}
|
|
38
|
+
if (!value) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const match = /^(\d+(?:\.\d+)?)px$/.exec(value.trim());
|
|
42
|
+
return match ? Number(match[1]) : undefined;
|
|
43
|
+
}
|
|
44
|
+
function clampColumnWidth(column, width) {
|
|
45
|
+
var _a;
|
|
46
|
+
const minWidth = (_a = parsePixelSize(column.minWidth)) !== null && _a !== void 0 ? _a : DEFAULT_COLUMN_RESIZE_MIN_WIDTH;
|
|
47
|
+
const maxWidth = parsePixelSize(column.maxWidth);
|
|
48
|
+
const roundedWidth = Math.round(width);
|
|
49
|
+
const clampedWidth = Math.max(minWidth, roundedWidth);
|
|
50
|
+
return maxWidth !== undefined
|
|
51
|
+
? Math.min(clampedWidth, maxWidth)
|
|
52
|
+
: clampedWidth;
|
|
53
|
+
}
|
|
54
|
+
function getColumnResizeMinWidth(column) {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
return ((_b = (_a = parsePixelSize(column.resizeMinWidth)) !== null && _a !== void 0 ? _a : parsePixelSize(column.minWidth)) !== null && _b !== void 0 ? _b : DEFAULT_COLUMN_RESIZE_MIN_WIDTH);
|
|
57
|
+
}
|
|
58
|
+
function getColumnResizeMaxWidth(column) {
|
|
59
|
+
var _a;
|
|
60
|
+
return (_a = parsePixelSize(column.resizeMaxWidth)) !== null && _a !== void 0 ? _a : Number.POSITIVE_INFINITY;
|
|
61
|
+
}
|
|
62
|
+
function getColumnResizeMaxWidthStyle(column) {
|
|
63
|
+
const maxWidth = getColumnResizeMaxWidth(column);
|
|
64
|
+
return Number.isFinite(maxWidth) ? `${maxWidth}px` : undefined;
|
|
65
|
+
}
|
|
66
|
+
function clampColumnResizeWidth(column, width) {
|
|
67
|
+
const minWidth = getColumnResizeMinWidth(column);
|
|
68
|
+
const maxWidth = getColumnResizeMaxWidth(column);
|
|
69
|
+
const roundedWidth = Math.round(width);
|
|
70
|
+
const clampedWidth = Math.max(minWidth, roundedWidth);
|
|
71
|
+
return Number.isFinite(maxWidth)
|
|
72
|
+
? Math.min(clampedWidth, maxWidth)
|
|
73
|
+
: clampedWidth;
|
|
74
|
+
}
|
|
75
|
+
function clampNumber(value, min, max) {
|
|
76
|
+
return Math.min(Math.max(value, min), max);
|
|
77
|
+
}
|
|
78
|
+
function getResolvedColumnWidth(column, columnWidths) {
|
|
79
|
+
const resizedWidth = columnWidths[column.key];
|
|
80
|
+
if (resizedWidth === undefined) {
|
|
81
|
+
return column.width;
|
|
82
|
+
}
|
|
83
|
+
return `${clampColumnWidth(column, resizedWidth)}px`;
|
|
84
|
+
}
|
|
85
|
+
function getResolvedResizableColumnWidth(column, columnWidths) {
|
|
86
|
+
return clampColumnResizeWidth(column, getColumnResizeBaseWidth(column, columnWidths));
|
|
87
|
+
}
|
|
88
|
+
function getRenderedColumnWidth({ column, columnWidths, resizing, }) {
|
|
89
|
+
if (resizing) {
|
|
90
|
+
return `${getResolvedResizableColumnWidth(column, columnWidths)}px`;
|
|
91
|
+
}
|
|
92
|
+
return getResolvedColumnWidth(column, columnWidths);
|
|
93
|
+
}
|
|
94
|
+
function getRenderedColumnMinWidth(column, resizing) {
|
|
95
|
+
return resizing ? `${getColumnResizeMinWidth(column)}px` : column.minWidth;
|
|
96
|
+
}
|
|
97
|
+
function getRenderedColumnMaxWidth(column, resizing) {
|
|
98
|
+
return resizing ? getColumnResizeMaxWidthStyle(column) : column.maxWidth;
|
|
99
|
+
}
|
|
100
|
+
function getColumnResizeBaseWidth(column, columnWidths, elementWidth) {
|
|
101
|
+
var _a, _b, _c, _d;
|
|
102
|
+
return ((_d = (_c = (_b = (_a = columnWidths[column.key]) !== null && _a !== void 0 ? _a : parsePixelSize(column.width)) !== null && _b !== void 0 ? _b : (elementWidth && elementWidth > 0 ? elementWidth : undefined)) !== null && _c !== void 0 ? _c : parsePixelSize(column.minWidth)) !== null && _d !== void 0 ? _d : DEFAULT_COLUMN_RESIZE_START_WIDTH);
|
|
103
|
+
}
|
|
104
|
+
function getColumnResizeLabel(column) {
|
|
105
|
+
if (column.visibilityLabel) {
|
|
106
|
+
return column.visibilityLabel;
|
|
107
|
+
}
|
|
108
|
+
if (typeof column.header === "string" ||
|
|
109
|
+
typeof column.header === "number") {
|
|
110
|
+
return String(column.header);
|
|
111
|
+
}
|
|
112
|
+
return column.key;
|
|
113
|
+
}
|
|
23
114
|
const TableHeader = React.forwardRef(({ className, ...props }, ref) => (_jsx("thead", { ref: ref, className: cn("sticky top-0 z-10 bg-[hsl(var(--table-header-background))] [&_tr]:border-b [&_tr]:border-[hsl(var(--table-border))] [&>tr]:bg-inherit", className), ...props })));
|
|
24
115
|
TableHeader.displayName = "TableHeader";
|
|
25
116
|
const TableBody = React.forwardRef(({ className, ...props }, ref) => (_jsx("tbody", { ref: ref, className: cn("[&_tr:last-child]:border-0", className), ...props })));
|
|
@@ -28,7 +119,7 @@ const TableFooter = React.forwardRef(({ className, ...props }, ref) => (_jsx("tf
|
|
|
28
119
|
TableFooter.displayName = "TableFooter";
|
|
29
120
|
const TableRow = React.forwardRef(({ className, ...props }, ref) => (_jsx("tr", { ref: ref, className: cn("border-b border-[hsl(var(--table-border))] bg-card text-card-foreground transition-colors data-[state=selected]:bg-muted", className), ...props })));
|
|
30
121
|
TableRow.displayName = "TableRow";
|
|
31
|
-
const TableHead = React.forwardRef(({ className, style, width, minWidth, maxWidth, wrap = false, ...props }, ref) => (_jsx("th", { ref: ref, className: cn("h-11 px-4 py-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0", wrap ? "whitespace-normal" : "whitespace-nowrap", className), style: getTableColumnSizingStyle({
|
|
122
|
+
const TableHead = React.forwardRef(({ className, style, width, minWidth, maxWidth, wrap = false, treatWidthAsMinWidth, containOverflow, ...props }, ref) => (_jsx("th", { ref: ref, className: cn("h-11 px-4 py-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0", wrap ? "whitespace-normal" : "whitespace-nowrap", overflowContainmentClassName({ containOverflow, wrap }), className), style: getTableColumnSizingStyle({
|
|
32
123
|
style: {
|
|
33
124
|
...style,
|
|
34
125
|
fontWeight: 500,
|
|
@@ -36,24 +127,43 @@ const TableHead = React.forwardRef(({ className, style, width, minWidth, maxWidt
|
|
|
36
127
|
width,
|
|
37
128
|
minWidth,
|
|
38
129
|
maxWidth,
|
|
130
|
+
treatWidthAsMinWidth,
|
|
39
131
|
}), ...props })));
|
|
40
132
|
TableHead.displayName = "TableHead";
|
|
41
|
-
const TableCell = React.forwardRef(({ className, style, width, minWidth, maxWidth, wrap = false, ...props }, ref) => (_jsx("td", { ref: ref, className: cn("h-12 px-4 py-2 align-middle text-card-foreground [&:has([role=checkbox])]:pr-0", wrap ? "whitespace-normal" : "whitespace-nowrap",
|
|
133
|
+
const TableCell = React.forwardRef(({ className, style, width, minWidth, maxWidth, wrap = false, treatWidthAsMinWidth, containOverflow, ...props }, ref) => (_jsx("td", { ref: ref, className: cn("h-12 px-4 py-2 align-middle text-card-foreground [&:has([role=checkbox])]:pr-0", wrap ? "whitespace-normal" : "whitespace-nowrap", overflowContainmentClassName({ containOverflow, wrap }), className), style: getTableColumnSizingStyle({
|
|
134
|
+
style,
|
|
135
|
+
width,
|
|
136
|
+
minWidth,
|
|
137
|
+
maxWidth,
|
|
138
|
+
treatWidthAsMinWidth,
|
|
139
|
+
}), ...props })));
|
|
42
140
|
TableCell.displayName = "TableCell";
|
|
43
141
|
const TableCaption = React.forwardRef(({ className, ...props }, ref) => (_jsx("caption", { ref: ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props })));
|
|
44
142
|
TableCaption.displayName = "TableCaption";
|
|
45
|
-
|
|
143
|
+
const STICKY_SCROLL_EDGE_THRESHOLD = 1;
|
|
144
|
+
function stickyClassName(sticky, kind, showShadow = false) {
|
|
46
145
|
if (!sticky)
|
|
47
146
|
return undefined;
|
|
48
147
|
const side = sticky === "left" ? "left-0" : "right-0";
|
|
49
|
-
const shadow =
|
|
50
|
-
? "
|
|
51
|
-
|
|
148
|
+
const shadow = showShadow
|
|
149
|
+
? sticky === "left"
|
|
150
|
+
? "shadow-[inset_-1px_0_0_0_hsl(var(--table-border)),_8px_0_12px_-10px_hsl(var(--foreground)_/_0.35)]"
|
|
151
|
+
: "shadow-[inset_1px_0_0_0_hsl(var(--table-border)),_-8px_0_12px_-10px_hsl(var(--foreground)_/_0.35)]"
|
|
152
|
+
: undefined;
|
|
52
153
|
const background = kind === "head" ? "bg-[hsl(var(--table-header-background))]" : "bg-card";
|
|
53
154
|
// z-20 on header cells so they layer above sticky body cells on the other axis.
|
|
54
155
|
const z = kind === "head" ? "z-20" : "z-10";
|
|
55
156
|
return cn("sticky", background, side, z, shadow);
|
|
56
157
|
}
|
|
158
|
+
function getStickyShadowVisibility(sticky, scrollState) {
|
|
159
|
+
if (sticky === "left") {
|
|
160
|
+
return scrollState.left;
|
|
161
|
+
}
|
|
162
|
+
if (sticky === "right") {
|
|
163
|
+
return scrollState.right;
|
|
164
|
+
}
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
57
167
|
function alignClassName(align) {
|
|
58
168
|
switch (align) {
|
|
59
169
|
case "center":
|
|
@@ -107,12 +217,32 @@ export const TABLE_SKELETON_PRESETS = {
|
|
|
107
217
|
})),
|
|
108
218
|
}),
|
|
109
219
|
};
|
|
110
|
-
function SortableTableHead({ field, children, currentSortField, currentSortDirection, onSort, className, allowWrap = false, width, minWidth, maxWidth, align, sortLabel, }) {
|
|
220
|
+
function SortableTableHead({ field, children, currentSortField, currentSortDirection, onSort, className, allowWrap = false, width, minWidth, maxWidth, align, sortLabel, resizeHandle, treatWidthAsMinWidth, containOverflow, }) {
|
|
111
221
|
const isSorted = currentSortField === field;
|
|
112
|
-
return (
|
|
113
|
-
|
|
114
|
-
|
|
222
|
+
return (_jsxs(TableHead, { className: cn(resizeHandle && "relative", alignClassName(align), className), wrap: allowWrap, width: width, minWidth: minWidth, maxWidth: maxWidth, treatWidthAsMinWidth: treatWidthAsMinWidth, containOverflow: containOverflow, children: [_jsxs("button", { type: "button", onClick: () => onSort(field), className: cn("-ml-1.5 flex h-7 cursor-pointer items-center gap-1 rounded px-1.5 py-0 font-medium transition-colors hover:text-foreground", containOverflow && "max-w-full overflow-hidden", allowWrap
|
|
223
|
+
? "max-w-full whitespace-normal text-left"
|
|
224
|
+
: "whitespace-nowrap", align === "right" && "ml-auto justify-end", align === "center" && "mx-auto justify-center"), style: { font: "inherit", color: "inherit", fontWeight: 500 }, "aria-label": `Sort by ${sortLabel !== null && sortLabel !== void 0 ? sortLabel : field}`, children: [_jsx("span", { className: cn("min-w-0", containOverflow && !allowWrap && "truncate", containOverflow && allowWrap && "break-words [overflow-wrap:anywhere]"), children: children }), _jsx("span", { className: "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center", children: isSorted ? (currentSortDirection === "asc" ? (_jsx(ArrowUpIcon, { className: "shrink-0", size: 14 })) : (_jsx(ArrowDownIcon, { className: "shrink-0", size: 14 }))) : (_jsx(ArrowUpDown, { className: "h-3.5 w-3.5 shrink-0 opacity-50" })) })] }), resizeHandle] }));
|
|
115
225
|
}
|
|
226
|
+
const TableColumnResizeHandle = React.forwardRef(function TableColumnResizeHandle({ column, nextColumn, currentWidth, minWidth, maxWidth, onResizeStart, onResizeByKeyboard, className, onClick, ...props }, ref) {
|
|
227
|
+
const label = getColumnResizeLabel(column);
|
|
228
|
+
return (_jsx("button", { ...props, ref: ref, type: "button", "aria-label": `Resize ${label} column`, title: `Resize ${label} column`, "aria-valuenow": currentWidth, "aria-valuemin": minWidth, "aria-valuemax": maxWidth, onPointerDown: (event) => onResizeStart(column, nextColumn, event), onClick: (event) => {
|
|
229
|
+
onClick === null || onClick === void 0 ? void 0 : onClick(event);
|
|
230
|
+
if (event.defaultPrevented) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
event.preventDefault();
|
|
234
|
+
event.stopPropagation();
|
|
235
|
+
}, onKeyDown: (event) => {
|
|
236
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
event.preventDefault();
|
|
240
|
+
event.stopPropagation();
|
|
241
|
+
onResizeByKeyboard(column, nextColumn, event.key === "ArrowLeft"
|
|
242
|
+
? -COLUMN_RESIZE_KEYBOARD_STEP
|
|
243
|
+
: COLUMN_RESIZE_KEYBOARD_STEP);
|
|
244
|
+
}, className: cn("group absolute right-0 top-0 z-[1] flex h-full w-4 cursor-col-resize touch-none items-center justify-center focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2", className), children: _jsx("span", { "aria-hidden": "true", className: "h-6 w-px rounded-full bg-[hsl(var(--table-border))] transition-colors group-hover:bg-primary group-focus-visible:bg-primary" }) }));
|
|
245
|
+
});
|
|
116
246
|
function getDefaultSkeleton(column) {
|
|
117
247
|
var _a, _b;
|
|
118
248
|
return {
|
|
@@ -149,23 +279,163 @@ function getVisibleColumns(columns, visibleColumnKeys) {
|
|
|
149
279
|
});
|
|
150
280
|
return visibleColumns;
|
|
151
281
|
}
|
|
152
|
-
function
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
282
|
+
function isStickyResizeBoundary(column, nextColumn) {
|
|
283
|
+
return Boolean(column.sticky === "right" || nextColumn.sticky);
|
|
284
|
+
}
|
|
285
|
+
function Table({ columns, rows, getRowKey, emptyState = (_jsx(EmptyState, { message: "No data available", description: "There are no rows to display in this table yet.", className: "border-0 bg-transparent px-0 py-6" })), toolbar, caption, className, containerClassName, tableClassName, rowClassName, rowTone, maxHeight, sorting, pagination, loading = false, loadingRows = 5, visibleColumnKeys, resizableColumns = false, columnWidths, defaultColumnWidths, onColumnWidthsChange, renderColumnResizeHandle, striped = false, onRowClick, onScroll, style, ...props }) {
|
|
156
286
|
const visibleColumns = getVisibleColumns(columns, visibleColumnKeys);
|
|
157
|
-
const
|
|
287
|
+
const isColumnResizingEnabled = resizableColumns || visibleColumns.some((column) => column.resizable);
|
|
288
|
+
// Use auto layout by default so the browser can grow a column to contain its
|
|
289
|
+
// nowrap header. Resizable columns need fixed layout so neighbour columns do
|
|
290
|
+
// not redistribute width while a handle is dragged.
|
|
291
|
+
const shouldUseFixedLayout = isColumnResizingEnabled;
|
|
292
|
+
const [uncontrolledColumnWidths, setUncontrolledColumnWidths] = React.useState(() => ({ ...(defaultColumnWidths !== null && defaultColumnWidths !== void 0 ? defaultColumnWidths : {}) }));
|
|
293
|
+
const resolvedColumnWidths = columnWidths !== null && columnWidths !== void 0 ? columnWidths : uncontrolledColumnWidths;
|
|
294
|
+
const columnWidthsRef = React.useRef(resolvedColumnWidths);
|
|
295
|
+
const resizeCleanupRef = React.useRef(null);
|
|
296
|
+
const tableContainerRef = React.useRef(null);
|
|
297
|
+
const [stickyScrollState, setStickyScrollState] = React.useState({
|
|
298
|
+
left: false,
|
|
299
|
+
right: false,
|
|
300
|
+
});
|
|
301
|
+
const updateStickyScrollState = React.useCallback((element = tableContainerRef.current) => {
|
|
302
|
+
if (!element) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const maxScrollLeft = Math.max(0, element.scrollWidth - element.clientWidth);
|
|
306
|
+
const scrollLeft = Math.max(0, element.scrollLeft);
|
|
307
|
+
const nextScrollState = {
|
|
308
|
+
left: scrollLeft > STICKY_SCROLL_EDGE_THRESHOLD,
|
|
309
|
+
right: scrollLeft < maxScrollLeft - STICKY_SCROLL_EDGE_THRESHOLD,
|
|
310
|
+
};
|
|
311
|
+
setStickyScrollState((currentScrollState) => currentScrollState.left === nextScrollState.left &&
|
|
312
|
+
currentScrollState.right === nextScrollState.right
|
|
313
|
+
? currentScrollState
|
|
314
|
+
: nextScrollState);
|
|
315
|
+
}, []);
|
|
316
|
+
React.useEffect(() => {
|
|
317
|
+
columnWidthsRef.current = resolvedColumnWidths;
|
|
318
|
+
}, [resolvedColumnWidths]);
|
|
319
|
+
React.useEffect(() => {
|
|
320
|
+
updateStickyScrollState();
|
|
321
|
+
});
|
|
322
|
+
React.useEffect(() => {
|
|
323
|
+
const element = tableContainerRef.current;
|
|
324
|
+
if (!element || typeof ResizeObserver === "undefined") {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const observer = new ResizeObserver(() => updateStickyScrollState(element));
|
|
328
|
+
observer.observe(element);
|
|
329
|
+
return () => observer.disconnect();
|
|
330
|
+
}, [updateStickyScrollState]);
|
|
331
|
+
React.useEffect(() => () => {
|
|
332
|
+
var _a;
|
|
333
|
+
(_a = resizeCleanupRef.current) === null || _a === void 0 ? void 0 : _a.call(resizeCleanupRef);
|
|
334
|
+
}, []);
|
|
335
|
+
const commitColumnWidths = React.useCallback((updater) => {
|
|
336
|
+
const nextColumnWidths = updater(columnWidthsRef.current);
|
|
337
|
+
columnWidthsRef.current = nextColumnWidths;
|
|
338
|
+
if (!columnWidths) {
|
|
339
|
+
setUncontrolledColumnWidths(nextColumnWidths);
|
|
340
|
+
}
|
|
341
|
+
onColumnWidthsChange === null || onColumnWidthsChange === void 0 ? void 0 : onColumnWidthsChange(nextColumnWidths);
|
|
342
|
+
}, [columnWidths, onColumnWidthsChange]);
|
|
343
|
+
const resizeColumnPairByDelta = React.useCallback((column, nextColumn, delta, startColumnWidths = columnWidthsRef.current) => {
|
|
344
|
+
const currentWidth = getResolvedResizableColumnWidth(column, startColumnWidths);
|
|
345
|
+
const nextWidth = getResolvedResizableColumnWidth(nextColumn, startColumnWidths);
|
|
346
|
+
const minDelta = Math.max(getColumnResizeMinWidth(column) - currentWidth, nextWidth - getColumnResizeMaxWidth(nextColumn));
|
|
347
|
+
const maxDelta = Math.min(getColumnResizeMaxWidth(column) - currentWidth, nextWidth - getColumnResizeMinWidth(nextColumn));
|
|
348
|
+
const resolvedDelta = clampNumber(delta, minDelta, maxDelta);
|
|
349
|
+
commitColumnWidths((currentColumnWidths) => ({
|
|
350
|
+
...currentColumnWidths,
|
|
351
|
+
[column.key]: Math.round(currentWidth + resolvedDelta),
|
|
352
|
+
[nextColumn.key]: Math.round(nextWidth - resolvedDelta),
|
|
353
|
+
}));
|
|
354
|
+
}, [commitColumnWidths]);
|
|
355
|
+
const resizeColumnByKeyboard = React.useCallback((column, nextColumn, delta) => {
|
|
356
|
+
resizeColumnPairByDelta(column, nextColumn, delta);
|
|
357
|
+
}, [resizeColumnPairByDelta]);
|
|
358
|
+
const startColumnResize = React.useCallback((column, nextColumn, event) => {
|
|
359
|
+
var _a;
|
|
360
|
+
event.preventDefault();
|
|
361
|
+
event.stopPropagation();
|
|
362
|
+
(_a = resizeCleanupRef.current) === null || _a === void 0 ? void 0 : _a.call(resizeCleanupRef);
|
|
363
|
+
const ownerDocument = event.currentTarget.ownerDocument;
|
|
364
|
+
const startX = event.clientX;
|
|
365
|
+
const startColumnWidths = columnWidthsRef.current;
|
|
366
|
+
const previousCursor = ownerDocument.documentElement.style.cursor;
|
|
367
|
+
ownerDocument.documentElement.style.cursor = "col-resize";
|
|
368
|
+
const handlePointerMove = (pointerEvent) => {
|
|
369
|
+
resizeColumnPairByDelta(column, nextColumn, pointerEvent.clientX - startX, startColumnWidths);
|
|
370
|
+
};
|
|
371
|
+
const handlePointerUp = () => {
|
|
372
|
+
var _a;
|
|
373
|
+
(_a = resizeCleanupRef.current) === null || _a === void 0 ? void 0 : _a.call(resizeCleanupRef);
|
|
374
|
+
};
|
|
375
|
+
const cleanup = () => {
|
|
376
|
+
ownerDocument.removeEventListener("pointermove", handlePointerMove);
|
|
377
|
+
ownerDocument.removeEventListener("pointerup", handlePointerUp);
|
|
378
|
+
ownerDocument.documentElement.style.cursor = previousCursor;
|
|
379
|
+
resizeCleanupRef.current = null;
|
|
380
|
+
};
|
|
381
|
+
resizeCleanupRef.current = cleanup;
|
|
382
|
+
ownerDocument.addEventListener("pointermove", handlePointerMove);
|
|
383
|
+
ownerDocument.addEventListener("pointerup", handlePointerUp);
|
|
384
|
+
}, [resizeColumnPairByDelta]);
|
|
385
|
+
const renderResizeHandle = React.useCallback((column, columnIndex) => {
|
|
386
|
+
var _a, _b;
|
|
387
|
+
const nextColumn = visibleColumns[columnIndex + 1];
|
|
388
|
+
const isResizable = (_a = column.resizable) !== null && _a !== void 0 ? _a : resizableColumns;
|
|
389
|
+
const isNextResizable = nextColumn && ((_b = nextColumn.resizable) !== null && _b !== void 0 ? _b : resizableColumns);
|
|
390
|
+
if (!isResizable || !nextColumn || !isNextResizable) {
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
const stickyResizeBoundary = isStickyResizeBoundary(column, nextColumn);
|
|
394
|
+
if (stickyResizeBoundary) {
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
const handle = (_jsx(TableColumnResizeHandle, { column: column, nextColumn: nextColumn, currentWidth: getResolvedResizableColumnWidth(column, resolvedColumnWidths), minWidth: getColumnResizeMinWidth(column), maxWidth: Number.isFinite(getColumnResizeMaxWidth(column))
|
|
398
|
+
? getColumnResizeMaxWidth(column)
|
|
399
|
+
: undefined, onResizeStart: startColumnResize, onResizeByKeyboard: resizeColumnByKeyboard }));
|
|
400
|
+
if (renderColumnResizeHandle) {
|
|
401
|
+
return renderColumnResizeHandle({ column, nextColumn, handle });
|
|
402
|
+
}
|
|
403
|
+
return handle;
|
|
404
|
+
}, [
|
|
405
|
+
resizableColumns,
|
|
406
|
+
renderColumnResizeHandle,
|
|
407
|
+
resizeColumnByKeyboard,
|
|
408
|
+
resolvedColumnWidths,
|
|
409
|
+
startColumnResize,
|
|
410
|
+
visibleColumns,
|
|
411
|
+
]);
|
|
412
|
+
const handleTableContainerScroll = React.useCallback((event) => {
|
|
413
|
+
onScroll === null || onScroll === void 0 ? void 0 : onScroll(event);
|
|
414
|
+
updateStickyScrollState(event.currentTarget);
|
|
415
|
+
}, [onScroll, updateStickyScrollState]);
|
|
416
|
+
const container = (_jsx(TableContainer, { ref: tableContainerRef, onScroll: handleTableContainerScroll, className: cn("w-full", loading && "pointer-events-none select-none", className, containerClassName), style: {
|
|
158
417
|
...style,
|
|
159
418
|
...(maxHeight !== undefined ? { maxHeight } : {}),
|
|
160
419
|
}, ...props, children: _jsxs(TableRoot, { className: cn(shouldUseFixedLayout && "table-fixed", tableClassName), children: [caption ? _jsx(TableCaption, { children: caption }) : null, _jsx("colgroup", { children: visibleColumns.map((column) => (_jsx("col", { style: getTableColumnSizingStyle({
|
|
161
|
-
width:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
420
|
+
width: getRenderedColumnWidth({
|
|
421
|
+
column,
|
|
422
|
+
columnWidths: resolvedColumnWidths,
|
|
423
|
+
resizing: isColumnResizingEnabled,
|
|
424
|
+
}),
|
|
425
|
+
minWidth: getRenderedColumnMinWidth(column, isColumnResizingEnabled),
|
|
426
|
+
maxWidth: getRenderedColumnMaxWidth(column, isColumnResizingEnabled),
|
|
427
|
+
treatWidthAsMinWidth: !isColumnResizingEnabled,
|
|
428
|
+
}) }, column.key))) }), _jsx(TableHeader, { children: _jsx(TableRow, { children: visibleColumns.map((column, columnIndex) => {
|
|
165
429
|
var _a;
|
|
166
430
|
const sortField = (_a = column.sortKey) !== null && _a !== void 0 ? _a : column.key;
|
|
167
431
|
const isSortable = column.sortable && sorting;
|
|
168
|
-
|
|
432
|
+
const columnWidth = getRenderedColumnWidth({
|
|
433
|
+
column,
|
|
434
|
+
columnWidths: resolvedColumnWidths,
|
|
435
|
+
resizing: isColumnResizingEnabled,
|
|
436
|
+
});
|
|
437
|
+
const resizeHandle = renderResizeHandle(column, columnIndex);
|
|
438
|
+
return (isSortable ? (_jsx(SortableTableHead, { field: sortField, currentSortField: sorting.field, currentSortDirection: sorting.direction, onSort: sorting.onSort, className: cn(stickyClassName(column.sticky, "head", getStickyShadowVisibility(column.sticky, stickyScrollState)), column.headerClassName), allowWrap: column.wrap, width: columnWidth, minWidth: getRenderedColumnMinWidth(column, isColumnResizingEnabled), maxWidth: getRenderedColumnMaxWidth(column, isColumnResizingEnabled), align: column.align, sortLabel: column.sortLabel, resizeHandle: resizeHandle, treatWidthAsMinWidth: !isColumnResizingEnabled, containOverflow: isColumnResizingEnabled, children: column.header }, column.key)) : (_jsxs(TableHead, { width: columnWidth, minWidth: getRenderedColumnMinWidth(column, isColumnResizingEnabled), maxWidth: getRenderedColumnMaxWidth(column, isColumnResizingEnabled), wrap: column.wrap, treatWidthAsMinWidth: !isColumnResizingEnabled, containOverflow: isColumnResizingEnabled, className: cn(resizeHandle && "relative", alignClassName(column.align), stickyClassName(column.sticky, "head", getStickyShadowVisibility(column.sticky, stickyScrollState)), column.headerClassName), children: [column.header, resizeHandle] }, column.key)));
|
|
169
439
|
}) }) }), _jsx(TableBody, { children: loading ? (_jsx(TableRowSkeleton, { rows: loadingRows, columns: visibleColumns.map((column) => { var _a; return (_a = column.skeleton) !== null && _a !== void 0 ? _a : getDefaultSkeleton(column); }) })) : rows.length ? (rows.map((row, rowIndex) => {
|
|
170
440
|
const resolvedTone = typeof rowTone === "function"
|
|
171
441
|
? rowTone(row, rowIndex)
|
|
@@ -178,10 +448,15 @@ function Table({ columns, rows, getRowKey, emptyState = (_jsx(EmptyState, { mess
|
|
|
178
448
|
? rowClassName(row, rowIndex)
|
|
179
449
|
: rowClassName), children: visibleColumns.map((column) => {
|
|
180
450
|
var _a, _b;
|
|
451
|
+
const columnWidth = getRenderedColumnWidth({
|
|
452
|
+
column,
|
|
453
|
+
columnWidths: resolvedColumnWidths,
|
|
454
|
+
resizing: isColumnResizingEnabled,
|
|
455
|
+
});
|
|
181
456
|
const value = (_b = (_a = column.cell) === null || _a === void 0 ? void 0 : _a.call(column, row, rowIndex)) !== null && _b !== void 0 ? _b : (column.accessorKey !== undefined
|
|
182
457
|
? row[column.accessorKey]
|
|
183
458
|
: null);
|
|
184
|
-
return (_jsx(TableCell, { width:
|
|
459
|
+
return (_jsx(TableCell, { width: columnWidth, minWidth: getRenderedColumnMinWidth(column, isColumnResizingEnabled), maxWidth: getRenderedColumnMaxWidth(column, isColumnResizingEnabled), wrap: column.wrap, treatWidthAsMinWidth: !isColumnResizingEnabled, containOverflow: isColumnResizingEnabled, className: cn(alignClassName(column.align), stickyClassName(column.sticky, "cell", getStickyShadowVisibility(column.sticky, stickyScrollState)), column.cellClassName), children: value }, column.key));
|
|
185
460
|
}) }, getRowKey(row, rowIndex)));
|
|
186
461
|
})) : (_jsx(TableRow, { className: "cursor-default hover:bg-card", children: _jsx(TableCell, { colSpan: Math.max(visibleColumns.length, 1), className: "p-6", children: emptyState }) })) })] }) }));
|
|
187
462
|
if (!pagination) {
|
package/dist/tabs.d.ts
CHANGED
|
@@ -55,8 +55,9 @@ export interface TabWithDropdownProps {
|
|
|
55
55
|
onSectionSelect?: (sectionId: string) => void;
|
|
56
56
|
activeSection?: string;
|
|
57
57
|
className?: string;
|
|
58
|
+
contentClassName?: string;
|
|
58
59
|
}
|
|
59
|
-
declare function TabWithDropdown({ value, label, sections, disabled, scrollOffset, onSectionSelect, activeSection, className, }: TabWithDropdownProps): import("react/jsx-runtime").JSX.Element;
|
|
60
|
+
declare function TabWithDropdown({ value, label, sections, disabled, scrollOffset, onSectionSelect, activeSection, className, contentClassName, }: TabWithDropdownProps): import("react/jsx-runtime").JSX.Element;
|
|
60
61
|
export interface TabsProps extends Omit<React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>, "children" | "value" | "defaultValue" | "onValueChange"> {
|
|
61
62
|
items: TabsItem[];
|
|
62
63
|
defaultValue?: string;
|