pixelize-design-library 2.4.2-beta.10 → 2.4.2-beta.11
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/Table/Table.d.ts +1 -1
- package/dist/Components/Table/Table.js +7 -3
- package/dist/Components/Table/TableProps.d.ts +4 -0
- package/dist/Components/Table/components/TableBody.js +40 -11
- package/dist/Components/Table/components/TableHeader.js +21 -8
- package/dist/Components/Table/variants/TableVariantContext.d.ts +4 -0
- package/dist/Components/Table/variants/TableVariantContext.js +17 -0
- package/dist/Components/Table/variants/classic.d.ts +6 -0
- package/dist/Components/Table/variants/classic.js +47 -0
- package/dist/Components/Table/variants/index.d.ts +7 -0
- package/dist/Components/Table/variants/index.js +27 -0
- package/dist/Components/Table/variants/pillInk.d.ts +6 -0
- package/dist/Components/Table/variants/pillInk.js +21 -0
- package/dist/Components/Table/variants/studio.d.ts +6 -0
- package/dist/Components/Table/variants/studio.js +50 -0
- package/dist/Components/Table/variants/tokens.d.ts +49 -0
- package/dist/Components/Table/variants/tokens.js +2 -0
- package/dist/esm/Components/Table/Table.js +7 -3
- package/dist/esm/Components/Table/components/TableBody.js +41 -12
- package/dist/esm/Components/Table/components/TableHeader.js +21 -8
- package/dist/esm/Components/Table/variants/TableVariantContext.js +13 -0
- package/dist/esm/Components/Table/variants/classic.js +43 -0
- package/dist/esm/Components/Table/variants/index.js +9 -0
- package/dist/esm/Components/Table/variants/pillInk.js +18 -0
- package/dist/esm/Components/Table/variants/studio.js +46 -0
- package/dist/esm/Components/Table/variants/tokens.js +1 -0
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { TableProps } from "./TableProps";
|
|
2
|
-
export default function Table({ data, columns, onSelection, isLoading, isCheckbox, headerBgColor, freezedBgColor, freezedTextColor, tableBorderColor, noBorders, isPagination, onRowClick, selections, isActionFreeze, preferences, paginationMode, infiniteScroll, hasMore, isLoadingMore, groupLoadMore, loadMoreText, loadMorePosition, loadMoreChunkSize, noOfRowsPerPage, totalRecords, onPagination, isTableSettings, headerActions, onGlobalSearch, onNoOfRowsPerPageChange, paginationSelectOptions, tableMaxHeight, minVisibleRows, maxVisibleRows, autoFitViewport, tableSettings, filterSidebar, loadingSkeletonRows, defaultVisibleColumns, density, stripe, groupColors, onAddItem, emptyState, onRefresh, }: TableProps): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export default function Table({ data, columns, onSelection, isLoading, isCheckbox, headerBgColor, freezedBgColor, freezedTextColor, tableBorderColor, noBorders, isPagination, onRowClick, selections, isActionFreeze, preferences, paginationMode, infiniteScroll, hasMore, isLoadingMore, groupLoadMore, loadMoreText, loadMorePosition, loadMoreChunkSize, noOfRowsPerPage, totalRecords, onPagination, isTableSettings, headerActions, onGlobalSearch, onNoOfRowsPerPageChange, paginationSelectOptions, tableMaxHeight, minVisibleRows, maxVisibleRows, autoFitViewport, tableSettings, filterSidebar, loadingSkeletonRows, defaultVisibleColumns, density, variant, stripe, groupColors, onAddItem, emptyState, onRefresh, }: TableProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,6 +10,9 @@ const react_2 = require("@chakra-ui/react");
|
|
|
10
10
|
const react_3 = require("@chakra-ui/react");
|
|
11
11
|
const framer_motion_1 = require("framer-motion");
|
|
12
12
|
const LeftFilterPane_1 = __importDefault(require("./filters/LeftFilterPane"));
|
|
13
|
+
const variants_1 = require("./variants");
|
|
14
|
+
const TableVariantContext_1 = require("./variants/TableVariantContext");
|
|
15
|
+
const accentText_1 = require("../../Theme/tokens/builders/accentText");
|
|
13
16
|
const Pagination_1 = __importDefault(require("./components/Pagination"));
|
|
14
17
|
const TableHeader_1 = __importDefault(require("./components/TableHeader"));
|
|
15
18
|
const TableBody_1 = __importDefault(require("./components/TableBody"));
|
|
@@ -34,11 +37,12 @@ function Table({ data, columns, onSelection, isLoading, isCheckbox = false, head
|
|
|
34
37
|
name: "",
|
|
35
38
|
page: "",
|
|
36
39
|
orgId: "",
|
|
37
|
-
}, paginationMode = "client", infiniteScroll = false, hasMore, isLoadingMore = false, groupLoadMore = false, loadMoreText = "Load more", loadMorePosition = "top", loadMoreChunkSize, noOfRowsPerPage = 50, totalRecords = 0, onPagination, isTableSettings = false, headerActions, onGlobalSearch, onNoOfRowsPerPageChange, paginationSelectOptions, tableMaxHeight, minVisibleRows, maxVisibleRows, autoFitViewport, tableSettings, filterSidebar, loadingSkeletonRows, defaultVisibleColumns, density = "normal", stripe, groupColors, onAddItem, emptyState, onRefresh,
|
|
40
|
+
}, paginationMode = "client", infiniteScroll = false, hasMore, isLoadingMore = false, groupLoadMore = false, loadMoreText = "Load more", loadMorePosition = "top", loadMoreChunkSize, noOfRowsPerPage = 50, totalRecords = 0, onPagination, isTableSettings = false, headerActions, onGlobalSearch, onNoOfRowsPerPageChange, paginationSelectOptions, tableMaxHeight, minVisibleRows, maxVisibleRows, autoFitViewport, tableSettings, filterSidebar, loadingSkeletonRows, defaultVisibleColumns, density = "normal", variant = "classic", stripe, groupColors, onAddItem, emptyState, onRefresh,
|
|
38
41
|
// onColumnFilter
|
|
39
42
|
}) {
|
|
40
43
|
var _a, _b, _c, _d;
|
|
41
44
|
const theme = (0, useCustomTheme_1.useCustomTheme)();
|
|
45
|
+
const variantTokens = (0, react_1.useMemo)(() => variants_1.TABLE_VARIANTS[variant](theme.colors, (0, accentText_1.isDarkCanvas)(theme.colors.backgroundColor.main)), [variant, theme.colors]);
|
|
42
46
|
const [columnsSearch, setColumnsSearch] = (0, react_1.useState)({});
|
|
43
47
|
const tableContainerRef = (0, react_1.useRef)(null);
|
|
44
48
|
const { isOpen: isFilterModalOpen, onOpen: onFilterModalOpen, onClose: onFilterModalClose } = (0, react_2.useDisclosure)();
|
|
@@ -357,7 +361,7 @@ function Table({ data, columns, onSelection, isLoading, isCheckbox = false, head
|
|
|
357
361
|
return acc + (Array.isArray(items) ? items.length : 0);
|
|
358
362
|
}, 0);
|
|
359
363
|
}, [filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.selected]);
|
|
360
|
-
return ((0, jsx_runtime_1.jsxs)(
|
|
364
|
+
return ((0, jsx_runtime_1.jsxs)(TableVariantContext_1.TableVariantProvider, { value: variantTokens, children: [(0, jsx_runtime_1.jsx)("style", { children: `
|
|
361
365
|
@keyframes pixelize-table-spin {
|
|
362
366
|
from { transform: rotate(0deg); }
|
|
363
367
|
to { transform: rotate(360deg); }
|
|
@@ -421,5 +425,5 @@ function Table({ data, columns, onSelection, isLoading, isCheckbox = false, head
|
|
|
421
425
|
backgroundColor: "transparent",
|
|
422
426
|
zIndex: 999,
|
|
423
427
|
},
|
|
424
|
-
}, children: [(0, jsx_runtime_1.jsx)(react_3.Thead, { position: "sticky", top: 0, zIndex: 4, bg:
|
|
428
|
+
}, children: [(0, jsx_runtime_1.jsx)(react_3.Thead, { position: "sticky", top: 0, zIndex: 4, bg: variantTokens.header.bg, children: (0, jsx_runtime_1.jsx)(TableHeader_1.default, { columns: columnsList, isCheckbox: isCheckbox, headerBgColor: headerBgColor !== null && headerBgColor !== void 0 ? headerBgColor : theme.colors.backgroundColor.muted, freezedBgColor: freezedBgColor !== null && freezedBgColor !== void 0 ? freezedBgColor : theme.colors.backgroundColor.secondary, freezedTextColor: freezedTextColor !== null && freezedTextColor !== void 0 ? freezedTextColor : theme.colors.text[500], handleSort: handleSort, headerRefs: headerRefs, columnWidths: columnWidths, columnsSort: columnsSort, noBorders: noBorders, handleCheckbox: handleCheckbox, isLoading: isTableLoading, checked: headerChecked, isContent: isContent, isLink: isLink, isActionFreeze: isActionFreeze, setColumnsSearch: setColumnsSearch, columnsSearch: columnsSearch, isSelecting: isSelecting }) }), (0, jsx_runtime_1.jsx)(react_3.Tbody, { children: (0, jsx_runtime_1.jsx)(TableBody_1.default, { data: isGrouped ? groupedSource : _filteredData, groups: renderGroups, onAddItem: onAddItem, columns: columnsList, startRow: isGrouped ? 0 : startRow, endRow: endRow, scrollContainerRef: tableContainerRef, isCheckbox: isCheckbox, columnWidths: columnWidths, noBorders: noBorders, freezedBgColor: freezedBgColor !== null && freezedBgColor !== void 0 ? freezedBgColor : theme.colors.backgroundColor.secondary, freezedTextColor: freezedTextColor !== null && freezedTextColor !== void 0 ? freezedTextColor : theme.colors.text[500], handleCheckbox: handleCheckbox, selections: selection, isLoading: isTableLoading, loadingSkeletonRows: loadingSkeletonRows, onRowClick: onRowClick, isContent: isContent, isLink: isLink, isActionFreeze: isActionFreeze, density: densityState, stripe: stripe, emptyState: emptyState }) })] }), canInfinite && isLoadingMore && ((0, jsx_runtime_1.jsxs)(react_2.Flex, { justify: "center", align: "center", py: 3, gap: 2, children: [(0, jsx_runtime_1.jsx)(react_2.Spinner, { size: "sm", color: theme.colors.accentText }), (0, jsx_runtime_1.jsx)(react_2.Box, { fontSize: "0.75rem", color: theme.colors.text[500], children: "Loading more\u2026" })] }))] }), groupLoadMoreActive && loadMorePosition === "bottom" && (groupLoadMoreCaption || canGroupLoadMore) && ((0, jsx_runtime_1.jsxs)(react_2.Flex, { justify: "center", align: "center", gap: 3, py: 3, borderTop: `0.063rem solid ${theme.colors.boxborder[200]}`, children: [groupLoadMoreCaption && ((0, jsx_runtime_1.jsx)(react_2.Box, { fontSize: "0.75rem", color: theme.colors.text[500], children: groupLoadMoreCaption })), canGroupLoadMore && ((0, jsx_runtime_1.jsx)(Button_1.default, { size: "xs", variant: "outline", colorScheme: "gray", isLoading: isLoadingMore, loadingText: loadMoreText, onClick: handleGroupLoadMore, label: loadMoreText }))] }))] })] })] })] }));
|
|
425
429
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Dispatch, MutableRefObject, ReactNode, SetStateAction } from "react";
|
|
2
2
|
import { FilterSidebarProps } from "../FilterSidebar/FilterSidebar";
|
|
3
3
|
import type { FilterValues } from "./filterTypes";
|
|
4
|
+
import type { TableVariant } from "./variants/tokens";
|
|
4
5
|
export type { FilterValues } from "./filterTypes";
|
|
6
|
+
export type { TableVariant, TableVariantTokens } from "./variants/tokens";
|
|
5
7
|
/** Dynamic row shape (cells, styles, callbacks). */
|
|
6
8
|
export type DataObject = Record<string, unknown>;
|
|
7
9
|
export type TableDensity = "compact" | "normal" | "comfortable";
|
|
@@ -16,6 +18,8 @@ export type TableProps = {
|
|
|
16
18
|
groupColors?: Record<string | number, string>;
|
|
17
19
|
onAddItem?: (groupValue: string | number) => void;
|
|
18
20
|
density?: TableDensity;
|
|
21
|
+
/** Visual preset. Defaults to `classic` — the table exactly as it shipped. */
|
|
22
|
+
variant?: TableVariant;
|
|
19
23
|
stripe?: boolean;
|
|
20
24
|
emptyState?: TableEmptyState | ReactNode;
|
|
21
25
|
handleExportChange?: (value: string) => void | undefined;
|
|
@@ -44,10 +44,11 @@ const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
|
44
44
|
const accentText_1 = require("../../../Theme/tokens/builders/accentText");
|
|
45
45
|
const TableLoading_1 = require("./TableLoading");
|
|
46
46
|
const TableActions_1 = __importDefault(require("./TableActions"));
|
|
47
|
-
const tableRowHoverStyle_1 = require("./tableRowHoverStyle");
|
|
48
47
|
const lucide_react_1 = require("lucide-react");
|
|
49
48
|
const Checkbox_1 = __importDefault(require("../../Checkbox/Checkbox"));
|
|
50
49
|
const TableGroupRow_1 = __importDefault(require("./TableGroupRow"));
|
|
50
|
+
const TableVariantContext_1 = require("../variants/TableVariantContext");
|
|
51
|
+
const pillInk_1 = require("../variants/pillInk");
|
|
51
52
|
// Density → row height (px) + cell vertical padding. The padding (not just the
|
|
52
53
|
// min-height) is what drives perceived row size, so compact tightens both.
|
|
53
54
|
const DENSITY_CONFIG = {
|
|
@@ -63,6 +64,9 @@ const getRowContent = (row) => typeof row.content === "function"
|
|
|
63
64
|
// the label is centered in whichever of white/black clears AA against that fill —
|
|
64
65
|
// the fill can be a consumer hex we can't know in advance is light or dark.
|
|
65
66
|
const StatusCell = ({ value, onSolid }) => ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "flex", alignItems: "center", justifyContent: "center", w: "100%", h: "100%", px: "0.5rem", fontSize: "0.75rem", fontWeight: 600, color: onSolid, textAlign: "center", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", children: value }));
|
|
67
|
+
// Studio's status cell: a contained chip on the tone's soft rung. Same tone pair
|
|
68
|
+
// the group header already uses, so an override hex behaves identically in both.
|
|
69
|
+
const StatusPill = ({ value, soft, ink, radius, }) => ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "inline-flex", alignItems: "center", maxW: "100%", px: "0.5rem", py: "0.125rem", borderRadius: radius, bg: soft, color: ink, fontSize: "0.75rem", fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", children: value }));
|
|
66
70
|
const EMPTY_HOVER = {};
|
|
67
71
|
const TableRow = react_2.default.memo(({ row, rowIndex, isChecked, isExpanded, isContent, isLink, isCheckbox, isLoading, isActionFreeze, columns, leftOffsets, noBorders, freezedBgColor, freezedTextColor, theme, borderStyle, selectedBg, selectedFrozenBg, hoverStyle, rowHeight, cellPy, palette, accentColor, ariaRowIndex, handleCheckbox, onRowClick, toggleRowExpansion, onMeasure, }) => {
|
|
68
72
|
// Measured-height virtualization: report this row's real height (main + any
|
|
@@ -101,15 +105,38 @@ const TableRow = react_2.default.memo(({ row, rowIndex, isChecked, isExpanded, i
|
|
|
101
105
|
onRowClick(row, { label: header.label, id: header.id });
|
|
102
106
|
}
|
|
103
107
|
}, [row, onRowClick]);
|
|
108
|
+
const variant = (0, TableVariantContext_1.useTableVariant)();
|
|
104
109
|
const firstDataColIndex = columns.findIndex((c) => !c.isHidden);
|
|
105
110
|
const accentSx = accentColor ? `inset 3px 0 0 ${accentColor}` : undefined;
|
|
111
|
+
// A selected row earns the leading bar only where a group accent isn't already
|
|
112
|
+
// claiming that edge — the group's identity is the scarcer signal.
|
|
113
|
+
const leadSx = variant.row.showSelectedBar && isChecked && !accentColor
|
|
114
|
+
? `inset 3px 0 0 ${variant.row.selectedBarColor}`
|
|
115
|
+
: accentSx;
|
|
116
|
+
const restsOnIndex = variant.slot.rest === "index";
|
|
117
|
+
const rowSx = {
|
|
118
|
+
...(variant.row.hoverScope === "row"
|
|
119
|
+
? { "&:hover > td[data-hoverable='true']": { backgroundColor: variant.row.hoverBg } }
|
|
120
|
+
: {}),
|
|
121
|
+
// opacity, not display: a hidden-by-display checkbox leaves the a11y tree and
|
|
122
|
+
// cannot be tabbed to, so `:focus-within` would never fire to bring it back.
|
|
123
|
+
...(restsOnIndex
|
|
124
|
+
? {
|
|
125
|
+
"& .table-slot-box": { opacity: isChecked ? 1 : 0 },
|
|
126
|
+
"& .table-slot-index": { opacity: isChecked ? 0 : 1 },
|
|
127
|
+
"&:hover .table-slot-box, &:focus-within .table-slot-box": { opacity: 1 },
|
|
128
|
+
"&:hover .table-slot-index, &:focus-within .table-slot-index": { opacity: 0 },
|
|
129
|
+
}
|
|
130
|
+
: {}),
|
|
131
|
+
};
|
|
106
132
|
// Pinned/frozen columns get a tinted, opaque background so the frozen pane reads
|
|
107
133
|
// as one piece with its header (and so sticky cells cover scrolling content).
|
|
108
134
|
const frozenCellBg = freezedBgColor !== null && freezedBgColor !== void 0 ? freezedBgColor : theme.colors.table.hover[100];
|
|
109
135
|
const cellStyles = row.cellStyle;
|
|
110
136
|
const rowStyle = row.rowStyle;
|
|
137
|
+
const chromeHoverable = rowStyle ? "false" : "true";
|
|
111
138
|
const rowContent = getRowContent(row);
|
|
112
|
-
return ((0, jsx_runtime_1.jsxs)(react_2.default.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_1.Tr, { ref: mainRowRef, "aria-rowindex": ariaRowIndex, opacity: isLoading ? 0.4 : 1, pointerEvents: isLoading ? "none" : "auto", transition: "opacity 0.2s", children: [isContent && ((0, jsx_runtime_1.jsx)(react_1.Td, { w: "6", p: 0, fontSize: 14, background: isChecked ? selectedFrozenBg : frozenCellBg, color: freezedTextColor, position: "sticky", borderBottom: borderStyle, boxShadow:
|
|
139
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.default.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_1.Tr, { ref: mainRowRef, "aria-rowindex": ariaRowIndex, opacity: isLoading ? 0.4 : 1, pointerEvents: isLoading ? "none" : "auto", transition: "opacity 0.2s", sx: rowSx, children: [isContent && ((0, jsx_runtime_1.jsx)(react_1.Td, { w: "6", p: 0, fontSize: 14, background: isChecked ? selectedFrozenBg : frozenCellBg, color: freezedTextColor, position: "sticky", borderBottom: borderStyle, boxShadow: leadSx, boxSizing: "border-box", "data-hoverable": chromeHoverable, left: "0px", zIndex: 1, className: "columns sticky-columns", children: !!(row === null || row === void 0 ? void 0 : row.content) && ((0, jsx_runtime_1.jsx)(react_1.IconButton, { "aria-label": isExpanded ? "Collapse row" : "Expand row", color: theme.colors.textMuted, icon: isExpanded ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { fontSize: 16 })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { fontSize: 16 })), _hover: { transform: "scale(1.1)" }, size: "sm", onClick: () => toggleRowExpansion(rowIndex), variant: "ghost" })) })), isCheckbox && ((0, jsx_runtime_1.jsx)(react_1.Td, { w: variant.slot.width, minW: variant.slot.width, px: variant.slot.centered ? 0 : undefined, textAlign: variant.slot.centered ? "center" : undefined, fontSize: 14, fontWeight: 600, color: theme.colors.background[50], textTransform: "capitalize", background: isChecked ? selectedFrozenBg : frozenCellBg, position: "sticky", borderBottom: borderStyle, boxShadow: !isContent ? leadSx : undefined, "data-hoverable": chromeHoverable, boxSizing: "border-box", left: "0px", zIndex: 1, className: "columns sticky-columns", children: (0, jsx_runtime_1.jsxs)(react_1.Box, { display: restsOnIndex ? "grid" : undefined, placeItems: "center", children: [restsOnIndex && ((0, jsx_runtime_1.jsx)(react_1.Box, { as: "span", className: "table-slot-index", gridArea: "1 / 1", color: variant.slot.indexInk, fontSize: "0.6875rem", fontWeight: 500, transition: "opacity 0.15s ease-in-out", sx: { fontVariantNumeric: "tabular-nums" }, children: rowIndex + 1 })), (0, jsx_runtime_1.jsx)(react_1.Box, { as: "span", className: restsOnIndex ? "table-slot-box" : undefined, gridArea: restsOnIndex ? "1 / 1" : undefined, display: "flex", alignItems: "center", justifyContent: "center", transition: "opacity 0.15s ease-in-out", children: (0, jsx_runtime_1.jsx)(Checkbox_1.default, { "aria-label": `Select row ${rowIndex + 1}`, onChange: () => handleCheckbox(getRowId(row)), isChecked: isChecked }) })] }) })), columns.map((header, headerIndex) => {
|
|
113
140
|
var _a, _b, _c;
|
|
114
141
|
if (header.isHidden)
|
|
115
142
|
return null;
|
|
@@ -124,13 +151,15 @@ const TableRow = react_2.default.memo(({ row, rowIndex, isChecked, isExpanded, i
|
|
|
124
151
|
const statusOnSolid = statusColor
|
|
125
152
|
? (_c = statusColor.onSolid) !== null && _c !== void 0 ? _c : (0, accentText_1.onFilled)(statusColor.solid, theme.colors.white, theme.colors.black)
|
|
126
153
|
: undefined;
|
|
127
|
-
|
|
154
|
+
const isBleed = variant.cells.statusFill === "bleed" && !!statusColor;
|
|
155
|
+
const canHover = !isBleed && !((cellStyles === null || cellStyles === void 0 ? void 0 : cellStyles[header.id]) || rowStyle);
|
|
156
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Td, { maxWidth: 500, minWidth: 120, height: `${rowHeight}px`, py: isBleed ? 0 : cellPy, px: isBleed ? 0 : undefined, onClick: () => handleCellClick(header), fontSize: 14, fontWeight: 400, position: isFrozen ? "sticky" : undefined, left: isFrozen ? leftOffsets[headerIndex] : undefined, zIndex: isFrozen ? 1 : 0, background: isBleed ? statusColor.solid : isChecked ? (isFrozen ? selectedFrozenBg : selectedBg) : isFrozen ? frozenCellBg : theme.colors.background[50], textOverflow: "ellipsis", boxShadow: isFirstDataCell ? leadSx : undefined, borderBottom: noBorders
|
|
128
157
|
? "none"
|
|
129
|
-
: `0.063rem solid ${
|
|
158
|
+
: `0.063rem solid ${isFrozen || isChecked
|
|
159
|
+
? variant.row.frozenRuleColor
|
|
160
|
+
: variant.row.ruleColor}`, className: `columns ${isFrozen ? "sticky-columns" : "scrollable-columns"}`, boxSizing: "border-box", color: isBleed ? statusOnSolid : variant.cells.ink, "data-hoverable": canHover ? "true" : "false", _hover: variant.row.hoverScope === "row" || !canHover
|
|
130
161
|
? EMPTY_HOVER
|
|
131
|
-
:
|
|
132
|
-
? EMPTY_HOVER
|
|
133
|
-
: hoverStyle, children: isStatus && statusColor ? ((0, jsx_runtime_1.jsx)(StatusCell, { value: (0, table_1.normalizeTableCellValue)(row[header.id]), onSolid: statusOnSolid })) : ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "block", overflow: "hidden", whiteSpace: "normal", overflowWrap: "break-word", children: (0, table_1.normalizeTableCellValue)(header.node ? header.node(row) : row[header.id]) })) }, headerIndex + 1));
|
|
162
|
+
: hoverStyle, children: isBleed ? ((0, jsx_runtime_1.jsx)(StatusCell, { value: (0, table_1.normalizeTableCellValue)(row[header.id]), onSolid: statusOnSolid })) : isStatus && statusColor ? ((0, jsx_runtime_1.jsx)(StatusPill, { value: (0, table_1.normalizeTableCellValue)(row[header.id]), soft: statusColor.soft, ink: (0, pillInk_1.resolvePillInk)(statusColor.text, statusColor.soft, theme.colors.background[50]), radius: variant.cells.pillRadius })) : ((0, jsx_runtime_1.jsx)(react_1.Box, { display: "block", overflow: "hidden", whiteSpace: "normal", overflowWrap: "break-word", children: (0, table_1.normalizeTableCellValue)(header.node ? header.node(row) : row[header.id]) })) }, headerIndex + 1));
|
|
134
163
|
}), isLink && ((0, jsx_runtime_1.jsx)(react_1.Td, { w: 2, p: 0, fontSize: 14, background: isChecked ? (isActionFreeze ? selectedFrozenBg : selectedBg) : isActionFreeze ? frozenCellBg : theme.colors.background[50], color: freezedTextColor, position: isActionFreeze ? "sticky" : "relative", borderBottom: borderStyle, boxSizing: "border-box", right: 0, zIndex: 1, className: `columns sticky-columns${isActionFreeze ? "-right" : ""}`, children: (row.onLink || row.onEdit || row.onDelete) ? ((0, jsx_runtime_1.jsx)(TableActions_1.default, { row: row })) : null }))] }), rowContent && isExpanded && ((0, jsx_runtime_1.jsx)(react_1.Tr, { ref: expandedRowRef, children: (0, jsx_runtime_1.jsx)(react_1.Td, { colSpan: columns.length +
|
|
135
164
|
(isCheckbox ? 1 : 0) +
|
|
136
165
|
(isContent ? 1 : 0) +
|
|
@@ -139,6 +168,7 @@ const TableRow = react_2.default.memo(({ row, rowIndex, isChecked, isExpanded, i
|
|
|
139
168
|
const TableBody = ({ data, isCheckbox, columns, startRow, columnWidths, freezedBgColor, freezedTextColor, noBorders, handleCheckbox, selections, isLoading, onRowClick, isContent, isLink, isActionFreeze, loadingSkeletonRows, scrollContainerRef, density, accentColors, groups, onAddItem, emptyState, }) => {
|
|
140
169
|
var _a, _b, _c;
|
|
141
170
|
const theme = (0, useCustomTheme_1.useCustomTheme)();
|
|
171
|
+
const variant = (0, TableVariantContext_1.useTableVariant)();
|
|
142
172
|
const [expandedRows, setExpandedRows] = (0, react_2.useState)(new Set());
|
|
143
173
|
const [collapsedGroups, setCollapsedGroups] = (0, react_2.useState)(new Set());
|
|
144
174
|
const toggleGroup = (0, react_2.useCallback)((value) => {
|
|
@@ -284,17 +314,16 @@ const TableBody = ({ data, isCheckbox, columns, startRow, columnWidths, freezedB
|
|
|
284
314
|
const checkboxOffset = isCheckbox ? 50 : 0;
|
|
285
315
|
return columnWidths.map((_, idx) => columnWidths.slice(0, idx).reduce((sum, w) => sum + w, 0) + checkboxOffset);
|
|
286
316
|
}, [columnWidths, isCheckbox]);
|
|
287
|
-
const borderStyle = (0, react_2.useMemo)(() => noBorders ? "none" : `0.063rem solid ${
|
|
317
|
+
const borderStyle = (0, react_2.useMemo)(() => noBorders ? "none" : `0.063rem solid ${variant.row.ruleColor}`, [noBorders, variant.row.ruleColor]);
|
|
288
318
|
// Selected-row tint applied per-cell (NOT a blanket `& td` override) so status
|
|
289
319
|
// cells keep their solid color + white text instead of white-on-tint.
|
|
290
|
-
const selectedBg =
|
|
320
|
+
const selectedBg = variant.row.selectedBg;
|
|
291
321
|
// Sticky/frozen cells overlay scrolling content, so their selected background
|
|
292
322
|
// must be OPAQUE — paint the (translucent) tint over an opaque base.
|
|
293
323
|
const selectedFrozenBg = `linear-gradient(0deg, ${selectedBg}, ${selectedBg}), ${theme.colors.background[50]}`;
|
|
294
324
|
// Dark mode lifts the hover fill to `table.hover[500]`; `[300]` sits ~1.2:1 from the canvas.
|
|
295
325
|
// No ink flip needed — see `tableRowHoverStyle.ts`.
|
|
296
|
-
const
|
|
297
|
-
const hoverStyle = (0, react_2.useMemo)(() => (0, tableRowHoverStyle_1.getTableRowHoverStyle)(theme.colors, isDark), [theme.colors, isDark]);
|
|
326
|
+
const hoverStyle = (0, react_2.useMemo)(() => ({ backgroundColor: variant.row.hoverBg }), [variant.row.hoverBg]);
|
|
298
327
|
// Flatten groups → one sequence of header/row items so it can be windowed.
|
|
299
328
|
// Independent of scrollTop, so scrolling reuses it instead of re-flattening.
|
|
300
329
|
const groupItems = (0, react_2.useMemo)(() => {
|
|
@@ -12,6 +12,7 @@ const accentText_1 = require("../../../Theme/tokens/builders/accentText");
|
|
|
12
12
|
const TableFilters_1 = __importDefault(require("../filters/TableFilters"));
|
|
13
13
|
const lucide_react_1 = require("lucide-react");
|
|
14
14
|
const Checkbox_1 = __importDefault(require("../../Checkbox/Checkbox"));
|
|
15
|
+
const TableVariantContext_1 = require("../variants/TableVariantContext");
|
|
15
16
|
const TableHeader = ({ columns, isCheckbox, handleSort, headerRefs, columnWidths, columnsSort, headerBgColor, freezedBgColor, freezedTextColor, noBorders, handleCheckbox, checked, isLoading, isContent, isLink, isActionFreeze, setColumnsSearch, columnsSearch, isSelecting, }) => {
|
|
16
17
|
const [openFilterId, setOpenFilterId] = (0, react_2.useState)(null);
|
|
17
18
|
return ((0, jsx_runtime_1.jsxs)(react_1.Tr, { pr: 0, "aria-rowindex": 1, children: [isContent && (0, jsx_runtime_1.jsx)(ContentSpacerCell, { noBorders: noBorders }), isCheckbox && ((0, jsx_runtime_1.jsx)(SelectAllCell, { freezedTextColor: freezedTextColor, noBorders: noBorders, isSelecting: isSelecting, isLoading: isLoading, checked: checked, handleCheckbox: handleCheckbox })), columns.map((header, index) => {
|
|
@@ -23,30 +24,33 @@ const TableHeader = ({ columns, isCheckbox, handleSort, headerRefs, columnWidths
|
|
|
23
24
|
exports.default = (0, react_2.memo)(TableHeader);
|
|
24
25
|
const SelectAllCell = (0, react_2.memo)(({ freezedTextColor, noBorders, isSelecting, isLoading, checked, handleCheckbox, }) => {
|
|
25
26
|
const theme = (0, useCustomTheme_1.useCustomTheme)();
|
|
26
|
-
|
|
27
|
+
const variant = (0, TableVariantContext_1.useTableVariant)();
|
|
28
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Th, { scope: "col", w: variant.slot.width, minW: variant.slot.width, px: variant.slot.centered ? 0 : undefined, textAlign: variant.slot.centered ? "center" : undefined, fontSize: 14, fontWeight: 600, color: freezedTextColor, textTransform: "capitalize", backgroundColor: variant.header.bg, position: "sticky", className: `columns sticky-columns`, left: "0px", zIndex: 9, borderBottom: noBorders ? "none" : `0.063rem solid ${variant.header.ruleColor}`, children: (0, jsx_runtime_1.jsx)(react_1.Box, { display: "flex", alignItems: "center", justifyContent: variant.slot.centered ? "center" : "flex-start", children: isSelecting ? ((0, jsx_runtime_1.jsx)(react_1.Spinner, { size: "sm", color: theme.colors.accentText })) : ((0, jsx_runtime_1.jsx)(Checkbox_1.default, { "aria-label": "Select all rows", variant: "outline", onChange: () => handleCheckbox(0), isChecked: isLoading ? false : checked === true, isIndeterminate: checked === "indeterminate" })) }) }));
|
|
27
29
|
});
|
|
28
30
|
const ContentSpacerCell = (0, react_2.memo)(({ noBorders }) => {
|
|
29
|
-
const
|
|
30
|
-
return ((0, jsx_runtime_1.jsx)(react_1.Th, { scope: "col", w: 6, minW: "35px", p: 0, backgroundColor:
|
|
31
|
+
const variant = (0, TableVariantContext_1.useTableVariant)();
|
|
32
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Th, { scope: "col", w: 6, minW: "35px", p: 0, backgroundColor: variant.header.bg, borderBottom: noBorders ? "none" : `0.063rem solid ${variant.header.ruleColor}`, position: "sticky", className: `columns sticky-columns`, left: "0px", zIndex: 1 }));
|
|
31
33
|
});
|
|
32
34
|
const ViewSpacerCell = (0, react_2.memo)(({ noBorders, isActionFreeze, }) => {
|
|
33
|
-
const
|
|
34
|
-
return ((0, jsx_runtime_1.jsx)(react_1.Th, { scope: "col", w: 2, p: 0, minW: "2.065rem", backgroundColor:
|
|
35
|
+
const variant = (0, TableVariantContext_1.useTableVariant)();
|
|
36
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Th, { scope: "col", w: 2, p: 0, minW: "2.065rem", backgroundColor: variant.header.bg, borderBottom: noBorders ? "none" : `0.063rem solid ${variant.header.ruleColor}`, position: isActionFreeze ? "sticky" : "relative", className: `columns sticky-columns`, right: "0px", zIndex: 1 }));
|
|
35
37
|
});
|
|
36
38
|
const SortingIcon = (0, react_2.memo)(({ label, sortState, isVisible, handleSortClick, }) => {
|
|
37
39
|
const theme = (0, useCustomTheme_1.useCustomTheme)();
|
|
40
|
+
const variant = (0, TableVariantContext_1.useTableVariant)();
|
|
38
41
|
return ((0, jsx_runtime_1.jsxs)(react_1.Box, { as: "button", type: "button", "aria-label": `Sort by ${label}`, display: "inline-flex", alignItems: "center", justifyContent: "center", cursor: "pointer", ml: 2, p: 0, border: "none", bg: "transparent", lineHeight: "1", onClick: handleSortClick, transition: "color 0.2s ease-in-out, opacity 0.2s ease-in-out",
|
|
39
42
|
// Kept out of view until hover/focus so the header looks exactly as it did,
|
|
40
43
|
// while staying in the DOM and reachable by Tab.
|
|
41
44
|
opacity: isVisible ? 1 : 0, _focus: { opacity: 1 }, _focusVisible: { opacity: 1 }, color: theme.colors.textMuted, _hover: {
|
|
42
45
|
opacity: 1,
|
|
43
|
-
color: (0, accentText_1.accentTextOnCanvas)(theme.colors.secondary,
|
|
46
|
+
color: (0, accentText_1.accentTextOnCanvas)(theme.colors.secondary, variant.header.bg),
|
|
44
47
|
}, children: [sortState === "none" && (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronsUpDown, { size: 14 }), sortState === "asc" && (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronUp, { size: 14 }), sortState === "desc" && (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { size: 14 })] }));
|
|
45
48
|
});
|
|
46
49
|
const ColumnHeader = (0, react_2.memo)(({ header, index, columnWidths, isCheckbox, noBorders, columnsSort, headerRefs, columnsSearch, setColumnsSearch, handleSort, openFilterId, setOpenFilterId, }) => {
|
|
47
50
|
var _a;
|
|
48
51
|
const [isHovered, setIsHovered] = (0, react_2.useState)(false);
|
|
49
52
|
const theme = (0, useCustomTheme_1.useCustomTheme)();
|
|
53
|
+
const variant = (0, TableVariantContext_1.useTableVariant)();
|
|
50
54
|
const isFrozen = header.isFreeze;
|
|
51
55
|
const leftOffset = isFrozen
|
|
52
56
|
? (0, table_1.calculateLeftOffset)(columnWidths, index) + (isCheckbox ? 50 : 0)
|
|
@@ -82,7 +86,16 @@ const ColumnHeader = (0, react_2.memo)(({ header, index, columnWidths, isCheckbo
|
|
|
82
86
|
document.addEventListener("mouseup", onMouseUp);
|
|
83
87
|
};
|
|
84
88
|
const isSortActive = !!(isSorting === null || isSorting === void 0 ? void 0 : isSorting.direction) && isSorting.direction !== "none";
|
|
85
|
-
|
|
89
|
+
// Studio keeps the kebab out of the resting header — nine of them read louder than
|
|
90
|
+
// the labels. A column that is filtering or sorting keeps its control on show.
|
|
91
|
+
const showActions = variant.header.actions === "always" ||
|
|
92
|
+
isHovered ||
|
|
93
|
+
isSortActive ||
|
|
94
|
+
openFilterId === header.id ||
|
|
95
|
+
!!columnsSearch[header.id];
|
|
96
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Th, { scope: "col", ref: (el) => (headerRefs.current[index] = el), "aria-sort": ariaSort, textTransform: variant.header.textTransform, fontSize: variant.header.fontSize, fontWeight: variant.header.fontWeight, letterSpacing: variant.header.letterSpacing, position: isFrozen ? "sticky" : undefined, left: isFrozen ? leftOffset : undefined, minWidth: 120, backgroundColor: variant.header.bg, maxWidth: 500, zIndex: isFrozen ? 2 : 1, py: 2, pr: 0, overflow: "hidden", borderTop: "none", borderBottom: noBorders ? "none" : `0.063rem solid ${variant.header.ruleColor}`, borderRight: noBorders || !variant.header.showColumnRule
|
|
97
|
+
? "none"
|
|
98
|
+
: `0.063rem solid ${variant.header.ruleColor}`, className: `columns ${isFrozen ? "sticky-columns" : "scrollable-columns"}`, height: variant.header.height, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: (0, jsx_runtime_1.jsxs)(react_1.Box, { display: "flex", color: variant.header.ink, lineHeight: "1.25rem", justifyContent: "space-between", alignItems: "center", position: "relative", children: [(0, jsx_runtime_1.jsx)(react_1.Box, { textOverflow: "ellipsis", whiteSpace: "nowrap", display: "inline-block", overflow: "hidden", children: header.label }), (0, jsx_runtime_1.jsxs)(react_1.Box, { display: "inline-flex", alignItems: "center", opacity: showActions ? 1 : 0, transition: "opacity 0.2s ease-in-out", _focusWithin: { opacity: 1 }, children: [header.isSort && ((0, jsx_runtime_1.jsx)(SortingIcon, { label: String(header.label), sortState: (_a = isSorting === null || isSorting === void 0 ? void 0 : isSorting.direction) !== null && _a !== void 0 ? _a : "none", isVisible: isHovered || isSortActive, handleSortClick: () => {
|
|
86
99
|
let direction = "asc";
|
|
87
100
|
if ((isSorting === null || isSorting === void 0 ? void 0 : isSorting.direction) === "asc") {
|
|
88
101
|
direction = "desc";
|
|
@@ -91,7 +104,7 @@ const ColumnHeader = (0, react_2.memo)(({ header, index, columnWidths, isCheckbo
|
|
|
91
104
|
direction = "none";
|
|
92
105
|
}
|
|
93
106
|
handleSort(header.id, direction);
|
|
94
|
-
} })), sortPriority > 0 && ((0, jsx_runtime_1.jsx)(react_1.Box, { as: "span", ml: 1, fontSize: "0.625rem", fontWeight: 700, lineHeight: "1", borderRadius: "full", px: "0.3rem", py: "0.1rem", bg: theme.colors.primary.opacity[16], color: (0, accentText_1.accentTextOnCanvas)(theme.colors.primary,
|
|
107
|
+
} })), sortPriority > 0 && ((0, jsx_runtime_1.jsx)(react_1.Box, { as: "span", ml: 1, fontSize: "0.625rem", fontWeight: 700, lineHeight: "1", borderRadius: "full", px: "0.3rem", py: "0.1rem", bg: theme.colors.primary.opacity[16], color: (0, accentText_1.accentTextOnCanvas)(theme.colors.primary, variant.header.bg), children: sortPriority })), (0, jsx_runtime_1.jsx)(TableFilters_1.default, { header: header, setColumnsSearch: (searchVal) => setColumnsSearch((prev) => ({
|
|
95
108
|
...prev,
|
|
96
109
|
[header.id]: searchVal,
|
|
97
110
|
})), columnsSearch: columnsSearch[header.id] || "", onClose: () => {
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TableVariantTokens } from "./tokens";
|
|
2
|
+
export declare const TableVariantProvider: import("react").Provider<TableVariantTokens | null>;
|
|
3
|
+
/** No provider means the table as it always was — the default is a variant, not a gap. */
|
|
4
|
+
export declare function useTableVariant(): TableVariantTokens;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TableVariantProvider = void 0;
|
|
4
|
+
exports.useTableVariant = useTableVariant;
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const useCustomTheme_1 = require("../../../Theme/useCustomTheme");
|
|
7
|
+
const accentText_1 = require("../../../Theme/tokens/builders/accentText");
|
|
8
|
+
const classic_1 = require("./classic");
|
|
9
|
+
const TableVariantContext = (0, react_1.createContext)(null);
|
|
10
|
+
exports.TableVariantProvider = TableVariantContext.Provider;
|
|
11
|
+
/** No provider means the table as it always was — the default is a variant, not a gap. */
|
|
12
|
+
function useTableVariant() {
|
|
13
|
+
const provided = (0, react_1.useContext)(TableVariantContext);
|
|
14
|
+
const theme = (0, useCustomTheme_1.useCustomTheme)();
|
|
15
|
+
const isDark = (0, accentText_1.isDarkCanvas)(theme.colors.backgroundColor.main);
|
|
16
|
+
return (0, react_1.useMemo)(() => provided !== null && provided !== void 0 ? provided : (0, classic_1.classicPreset)(theme.colors, isDark), [provided, theme.colors, isDark]);
|
|
17
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.classicPreset = void 0;
|
|
4
|
+
const accentText_1 = require("../../../Theme/tokens/builders/accentText");
|
|
5
|
+
const tableRowHoverStyle_1 = require("../components/tableRowHoverStyle");
|
|
6
|
+
/**
|
|
7
|
+
* The table as it shipped. Pinned by snapshot: every value here is read off the
|
|
8
|
+
* live component, so adding a variant cannot move it.
|
|
9
|
+
*/
|
|
10
|
+
const classicPreset = (colors, isDark) => {
|
|
11
|
+
const headerBg = colors.table.hover[200];
|
|
12
|
+
return {
|
|
13
|
+
header: {
|
|
14
|
+
bg: headerBg,
|
|
15
|
+
ink: (0, accentText_1.accentTextOnCanvas)(colors.secondary, headerBg),
|
|
16
|
+
fontSize: 13,
|
|
17
|
+
fontWeight: 600,
|
|
18
|
+
textTransform: "capitalize",
|
|
19
|
+
letterSpacing: "normal",
|
|
20
|
+
height: "45px",
|
|
21
|
+
ruleColor: colors.boxborder[200],
|
|
22
|
+
showColumnRule: true,
|
|
23
|
+
actions: "always",
|
|
24
|
+
},
|
|
25
|
+
row: {
|
|
26
|
+
hoverBg: (0, tableRowHoverStyle_1.getTableRowHoverStyle)(colors, isDark).backgroundColor,
|
|
27
|
+
hoverScope: "cell",
|
|
28
|
+
ruleColor: colors.boxborder[200],
|
|
29
|
+
frozenRuleColor: colors.boxborder[300],
|
|
30
|
+
selectedBg: colors.primary.opacity[16],
|
|
31
|
+
selectedBarColor: colors.primary[500],
|
|
32
|
+
showSelectedBar: false,
|
|
33
|
+
},
|
|
34
|
+
slot: {
|
|
35
|
+
width: "6",
|
|
36
|
+
rest: "checkbox",
|
|
37
|
+
indexInk: colors.textMuted,
|
|
38
|
+
centered: false,
|
|
39
|
+
},
|
|
40
|
+
cells: {
|
|
41
|
+
ink: colors.text[500],
|
|
42
|
+
statusFill: "bleed",
|
|
43
|
+
pillRadius: "0",
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
exports.classicPreset = classicPreset;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { classicPreset } from "./classic";
|
|
2
|
+
import { studioPreset } from "./studio";
|
|
3
|
+
import type { TableVariant, TableVariantPreset } from "./tokens";
|
|
4
|
+
/** Adding a variant is one file and one union member — no component changes. */
|
|
5
|
+
export declare const TABLE_VARIANTS: Record<TableVariant, TableVariantPreset>;
|
|
6
|
+
export * from "./tokens";
|
|
7
|
+
export { classicPreset, studioPreset };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.studioPreset = exports.classicPreset = exports.TABLE_VARIANTS = void 0;
|
|
18
|
+
const classic_1 = require("./classic");
|
|
19
|
+
Object.defineProperty(exports, "classicPreset", { enumerable: true, get: function () { return classic_1.classicPreset; } });
|
|
20
|
+
const studio_1 = require("./studio");
|
|
21
|
+
Object.defineProperty(exports, "studioPreset", { enumerable: true, get: function () { return studio_1.studioPreset; } });
|
|
22
|
+
/** Adding a variant is one file and one union member — no component changes. */
|
|
23
|
+
exports.TABLE_VARIANTS = {
|
|
24
|
+
classic: classic_1.classicPreset,
|
|
25
|
+
studio: studio_1.studioPreset,
|
|
26
|
+
};
|
|
27
|
+
__exportStar(require("./tokens"), exports);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A consumer `statusColors` hex is a FILL, and `pickTableColor` hands it straight back as ink
|
|
3
|
+
* over a 13%-alpha tint of itself — legible reversed out of a solid cell, ~1.9:1 on a pill.
|
|
4
|
+
* The palette path is already resolved by `resolveStatusTone`; this rescues the override path.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolvePillInk(ink: string, soft: string, surface: string): string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolvePillInk = resolvePillInk;
|
|
4
|
+
const accentText_1 = require("../../../Theme/tokens/builders/accentText");
|
|
5
|
+
const color_1 = require("../../../Theme/tokens/builders/color");
|
|
6
|
+
const outlineRung_1 = require("../../../Theme/tokens/builders/outlineRung");
|
|
7
|
+
const cache = new Map();
|
|
8
|
+
/**
|
|
9
|
+
* A consumer `statusColors` hex is a FILL, and `pickTableColor` hands it straight back as ink
|
|
10
|
+
* over a 13%-alpha tint of itself — legible reversed out of a solid cell, ~1.9:1 on a pill.
|
|
11
|
+
* The palette path is already resolved by `resolveStatusTone`; this rescues the override path.
|
|
12
|
+
*/
|
|
13
|
+
function resolvePillInk(ink, soft, surface) {
|
|
14
|
+
const key = `${ink}|${soft}|${surface}`;
|
|
15
|
+
const hit = cache.get(key);
|
|
16
|
+
if (hit !== undefined)
|
|
17
|
+
return hit;
|
|
18
|
+
const resolved = (0, outlineRung_1.liftToContrast)(ink, (0, color_1.compositeOver)(soft, surface), accentText_1.AA_NORMAL_TEXT);
|
|
19
|
+
cache.set(key, resolved);
|
|
20
|
+
return resolved;
|
|
21
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TableVariantPreset } from "./tokens";
|
|
2
|
+
/**
|
|
3
|
+
* Quieter chrome, one rule instead of a grid, and a slot that rests on the row
|
|
4
|
+
* number. Every colour is lifted against the surface it actually sits on.
|
|
5
|
+
*/
|
|
6
|
+
export declare const studioPreset: TableVariantPreset;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.studioPreset = void 0;
|
|
4
|
+
const outlineRung_1 = require("../../../Theme/tokens/builders/outlineRung");
|
|
5
|
+
const tableRowHoverStyle_1 = require("../components/tableRowHoverStyle");
|
|
6
|
+
/**
|
|
7
|
+
* Quieter chrome, one rule instead of a grid, and a slot that rests on the row
|
|
8
|
+
* number. Every colour is lifted against the surface it actually sits on.
|
|
9
|
+
*/
|
|
10
|
+
const studioPreset = (colors, isDark) => {
|
|
11
|
+
const surface = colors.background[50];
|
|
12
|
+
// Studio drops the per-column rule, so the one line left has to be visible on
|
|
13
|
+
// every brand — `boxborder[200]` measures as low as 1.09:1 on some of them.
|
|
14
|
+
const rule = (0, outlineRung_1.liftToContrast)(colors.boxborder[200], surface, outlineRung_1.CHROME_RULE);
|
|
15
|
+
return {
|
|
16
|
+
header: {
|
|
17
|
+
bg: surface,
|
|
18
|
+
ink: colors.text[500],
|
|
19
|
+
fontSize: 11,
|
|
20
|
+
fontWeight: 600,
|
|
21
|
+
textTransform: "uppercase",
|
|
22
|
+
letterSpacing: "0.06em",
|
|
23
|
+
height: "40px",
|
|
24
|
+
ruleColor: rule,
|
|
25
|
+
showColumnRule: false,
|
|
26
|
+
actions: "hover",
|
|
27
|
+
},
|
|
28
|
+
row: {
|
|
29
|
+
hoverBg: (0, tableRowHoverStyle_1.getTableRowHoverStyle)(colors, isDark).backgroundColor,
|
|
30
|
+
hoverScope: "row",
|
|
31
|
+
ruleColor: rule,
|
|
32
|
+
frozenRuleColor: rule,
|
|
33
|
+
selectedBg: (0, outlineRung_1.liftToContrast)(colors.primary[50], surface, outlineRung_1.MIN_PERCEPTIBLE_STEP),
|
|
34
|
+
selectedBarColor: colors.primary[500],
|
|
35
|
+
showSelectedBar: true,
|
|
36
|
+
},
|
|
37
|
+
slot: {
|
|
38
|
+
width: "3.5rem",
|
|
39
|
+
rest: "index",
|
|
40
|
+
indexInk: colors.textMuted,
|
|
41
|
+
centered: true,
|
|
42
|
+
},
|
|
43
|
+
cells: {
|
|
44
|
+
ink: colors.text[500],
|
|
45
|
+
statusFill: "pill",
|
|
46
|
+
pillRadius: "0.375rem",
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
exports.studioPreset = studioPreset;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A variant is a resolved token set, never a branch. Components read named tokens;
|
|
3
|
+
* only `Table.tsx` knows which variant is active.
|
|
4
|
+
*
|
|
5
|
+
* PURITY: presets take a palette and return values — no Chakra, no React, no CSS.
|
|
6
|
+
*/
|
|
7
|
+
import type { PaletteProps } from "../../../Theme/tokens/types";
|
|
8
|
+
export type TableVariant = "classic" | "studio";
|
|
9
|
+
export type TableSlotRest = "checkbox" | "index";
|
|
10
|
+
export type TableStatusFill = "bleed" | "pill";
|
|
11
|
+
export type TableHoverScope = "cell" | "row";
|
|
12
|
+
export type TableChromeReveal = "always" | "hover";
|
|
13
|
+
/** Every field required: a preset that forgets one is a compile error, not a runtime gap. */
|
|
14
|
+
export type TableVariantTokens = {
|
|
15
|
+
header: {
|
|
16
|
+
bg: string;
|
|
17
|
+
ink: string;
|
|
18
|
+
fontSize: number;
|
|
19
|
+
fontWeight: number;
|
|
20
|
+
textTransform: "capitalize" | "uppercase";
|
|
21
|
+
letterSpacing: string;
|
|
22
|
+
height: string;
|
|
23
|
+
ruleColor: string;
|
|
24
|
+
showColumnRule: boolean;
|
|
25
|
+
/** When the per-column filter kebab appears. Active columns always show it. */
|
|
26
|
+
actions: TableChromeReveal;
|
|
27
|
+
};
|
|
28
|
+
row: {
|
|
29
|
+
hoverBg: string;
|
|
30
|
+
hoverScope: TableHoverScope;
|
|
31
|
+
ruleColor: string;
|
|
32
|
+
frozenRuleColor: string;
|
|
33
|
+
selectedBg: string;
|
|
34
|
+
selectedBarColor: string;
|
|
35
|
+
showSelectedBar: boolean;
|
|
36
|
+
};
|
|
37
|
+
slot: {
|
|
38
|
+
width: string;
|
|
39
|
+
rest: TableSlotRest;
|
|
40
|
+
indexInk: string;
|
|
41
|
+
centered: boolean;
|
|
42
|
+
};
|
|
43
|
+
cells: {
|
|
44
|
+
ink: string;
|
|
45
|
+
statusFill: TableStatusFill;
|
|
46
|
+
pillRadius: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
export type TableVariantPreset = (colors: PaletteProps, isDark: boolean) => TableVariantTokens;
|
|
@@ -4,6 +4,9 @@ import { Box, TableContainer, Flex, Spinner, Popover, PopoverTrigger, PopoverCon
|
|
|
4
4
|
import { Table as ChakraTable, Tbody, Thead, Icon } from "@chakra-ui/react";
|
|
5
5
|
import { motion } from "framer-motion";
|
|
6
6
|
import LeftFilterPane from "./filters/LeftFilterPane.js";
|
|
7
|
+
import { TABLE_VARIANTS } from "./variants/index.js";
|
|
8
|
+
import { TableVariantProvider } from "./variants/TableVariantContext.js";
|
|
9
|
+
import { isDarkCanvas } from "../../Theme/tokens/builders/accentText.js";
|
|
7
10
|
import Pagination from "./components/Pagination.js";
|
|
8
11
|
import TableHeader from "./components/TableHeader.js";
|
|
9
12
|
import TableBody from "./components/TableBody.js";
|
|
@@ -28,11 +31,12 @@ export default function Table({ data, columns, onSelection, isLoading, isCheckbo
|
|
|
28
31
|
name: "",
|
|
29
32
|
page: "",
|
|
30
33
|
orgId: "",
|
|
31
|
-
}, paginationMode = "client", infiniteScroll = false, hasMore, isLoadingMore = false, groupLoadMore = false, loadMoreText = "Load more", loadMorePosition = "top", loadMoreChunkSize, noOfRowsPerPage = 50, totalRecords = 0, onPagination, isTableSettings = false, headerActions, onGlobalSearch, onNoOfRowsPerPageChange, paginationSelectOptions, tableMaxHeight, minVisibleRows, maxVisibleRows, autoFitViewport, tableSettings, filterSidebar, loadingSkeletonRows, defaultVisibleColumns, density = "normal", stripe, groupColors, onAddItem, emptyState, onRefresh,
|
|
34
|
+
}, paginationMode = "client", infiniteScroll = false, hasMore, isLoadingMore = false, groupLoadMore = false, loadMoreText = "Load more", loadMorePosition = "top", loadMoreChunkSize, noOfRowsPerPage = 50, totalRecords = 0, onPagination, isTableSettings = false, headerActions, onGlobalSearch, onNoOfRowsPerPageChange, paginationSelectOptions, tableMaxHeight, minVisibleRows, maxVisibleRows, autoFitViewport, tableSettings, filterSidebar, loadingSkeletonRows, defaultVisibleColumns, density = "normal", variant = "classic", stripe, groupColors, onAddItem, emptyState, onRefresh,
|
|
32
35
|
// onColumnFilter
|
|
33
36
|
}) {
|
|
34
37
|
var _a, _b, _c, _d;
|
|
35
38
|
const theme = useCustomTheme();
|
|
39
|
+
const variantTokens = useMemo(() => TABLE_VARIANTS[variant](theme.colors, isDarkCanvas(theme.colors.backgroundColor.main)), [variant, theme.colors]);
|
|
36
40
|
const [columnsSearch, setColumnsSearch] = useState({});
|
|
37
41
|
const tableContainerRef = useRef(null);
|
|
38
42
|
const { isOpen: isFilterModalOpen, onOpen: onFilterModalOpen, onClose: onFilterModalClose } = useDisclosure();
|
|
@@ -351,7 +355,7 @@ export default function Table({ data, columns, onSelection, isLoading, isCheckbo
|
|
|
351
355
|
return acc + (Array.isArray(items) ? items.length : 0);
|
|
352
356
|
}, 0);
|
|
353
357
|
}, [filterSidebar === null || filterSidebar === void 0 ? void 0 : filterSidebar.selected]);
|
|
354
|
-
return (_jsxs(
|
|
358
|
+
return (_jsxs(TableVariantProvider, { value: variantTokens, children: [_jsx("style", { children: `
|
|
355
359
|
@keyframes pixelize-table-spin {
|
|
356
360
|
from { transform: rotate(0deg); }
|
|
357
361
|
to { transform: rotate(360deg); }
|
|
@@ -415,5 +419,5 @@ export default function Table({ data, columns, onSelection, isLoading, isCheckbo
|
|
|
415
419
|
backgroundColor: "transparent",
|
|
416
420
|
zIndex: 999,
|
|
417
421
|
},
|
|
418
|
-
}, children: [_jsx(Thead, { position: "sticky", top: 0, zIndex: 4, bg:
|
|
422
|
+
}, children: [_jsx(Thead, { position: "sticky", top: 0, zIndex: 4, bg: variantTokens.header.bg, children: _jsx(TableHeader, { columns: columnsList, isCheckbox: isCheckbox, headerBgColor: headerBgColor !== null && headerBgColor !== void 0 ? headerBgColor : theme.colors.backgroundColor.muted, freezedBgColor: freezedBgColor !== null && freezedBgColor !== void 0 ? freezedBgColor : theme.colors.backgroundColor.secondary, freezedTextColor: freezedTextColor !== null && freezedTextColor !== void 0 ? freezedTextColor : theme.colors.text[500], handleSort: handleSort, headerRefs: headerRefs, columnWidths: columnWidths, columnsSort: columnsSort, noBorders: noBorders, handleCheckbox: handleCheckbox, isLoading: isTableLoading, checked: headerChecked, isContent: isContent, isLink: isLink, isActionFreeze: isActionFreeze, setColumnsSearch: setColumnsSearch, columnsSearch: columnsSearch, isSelecting: isSelecting }) }), _jsx(Tbody, { children: _jsx(TableBody, { data: isGrouped ? groupedSource : _filteredData, groups: renderGroups, onAddItem: onAddItem, columns: columnsList, startRow: isGrouped ? 0 : startRow, endRow: endRow, scrollContainerRef: tableContainerRef, isCheckbox: isCheckbox, columnWidths: columnWidths, noBorders: noBorders, freezedBgColor: freezedBgColor !== null && freezedBgColor !== void 0 ? freezedBgColor : theme.colors.backgroundColor.secondary, freezedTextColor: freezedTextColor !== null && freezedTextColor !== void 0 ? freezedTextColor : theme.colors.text[500], handleCheckbox: handleCheckbox, selections: selection, isLoading: isTableLoading, loadingSkeletonRows: loadingSkeletonRows, onRowClick: onRowClick, isContent: isContent, isLink: isLink, isActionFreeze: isActionFreeze, density: densityState, stripe: stripe, emptyState: emptyState }) })] }), canInfinite && isLoadingMore && (_jsxs(Flex, { justify: "center", align: "center", py: 3, gap: 2, children: [_jsx(Spinner, { size: "sm", color: theme.colors.accentText }), _jsx(Box, { fontSize: "0.75rem", color: theme.colors.text[500], children: "Loading more\u2026" })] }))] }), groupLoadMoreActive && loadMorePosition === "bottom" && (groupLoadMoreCaption || canGroupLoadMore) && (_jsxs(Flex, { justify: "center", align: "center", gap: 3, py: 3, borderTop: `0.063rem solid ${theme.colors.boxborder[200]}`, children: [groupLoadMoreCaption && (_jsx(Box, { fontSize: "0.75rem", color: theme.colors.text[500], children: groupLoadMoreCaption })), canGroupLoadMore && (_jsx(Button, { size: "xs", variant: "outline", colorScheme: "gray", isLoading: isLoadingMore, loadingText: loadMoreText, onClick: handleGroupLoadMore, label: loadMoreText }))] }))] })] })] })] }));
|
|
419
423
|
}
|
|
@@ -3,13 +3,14 @@ import { Box, IconButton, Spinner, Td, Tr } from "@chakra-ui/react";
|
|
|
3
3
|
import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { normalizeTableCellValue, buildTablePalette, pickTableColor } from "../../../Utils/table.js";
|
|
5
5
|
import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
|
|
6
|
-
import { onFilled
|
|
6
|
+
import { onFilled } from "../../../Theme/tokens/builders/accentText.js";
|
|
7
7
|
import { TableBodyLoading } from "./TableLoading.js";
|
|
8
8
|
import TableActions from "./TableActions.js";
|
|
9
|
-
import { getTableRowHoverStyle } from "./tableRowHoverStyle.js";
|
|
10
9
|
import { ChevronDown, ChevronRight } from "lucide-react";
|
|
11
10
|
import CheckBox from "../../Checkbox/Checkbox.js";
|
|
12
11
|
import TableGroupRow from "./TableGroupRow.js";
|
|
12
|
+
import { useTableVariant } from "../variants/TableVariantContext.js";
|
|
13
|
+
import { resolvePillInk } from "../variants/pillInk.js";
|
|
13
14
|
// Density → row height (px) + cell vertical padding. The padding (not just the
|
|
14
15
|
// min-height) is what drives perceived row size, so compact tightens both.
|
|
15
16
|
const DENSITY_CONFIG = {
|
|
@@ -25,6 +26,9 @@ const getRowContent = (row) => typeof row.content === "function"
|
|
|
25
26
|
// the label is centered in whichever of white/black clears AA against that fill —
|
|
26
27
|
// the fill can be a consumer hex we can't know in advance is light or dark.
|
|
27
28
|
const StatusCell = ({ value, onSolid }) => (_jsx(Box, { display: "flex", alignItems: "center", justifyContent: "center", w: "100%", h: "100%", px: "0.5rem", fontSize: "0.75rem", fontWeight: 600, color: onSolid, textAlign: "center", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", children: value }));
|
|
29
|
+
// Studio's status cell: a contained chip on the tone's soft rung. Same tone pair
|
|
30
|
+
// the group header already uses, so an override hex behaves identically in both.
|
|
31
|
+
const StatusPill = ({ value, soft, ink, radius, }) => (_jsx(Box, { display: "inline-flex", alignItems: "center", maxW: "100%", px: "0.5rem", py: "0.125rem", borderRadius: radius, bg: soft, color: ink, fontSize: "0.75rem", fontWeight: 600, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", children: value }));
|
|
28
32
|
const EMPTY_HOVER = {};
|
|
29
33
|
const TableRow = React.memo(({ row, rowIndex, isChecked, isExpanded, isContent, isLink, isCheckbox, isLoading, isActionFreeze, columns, leftOffsets, noBorders, freezedBgColor, freezedTextColor, theme, borderStyle, selectedBg, selectedFrozenBg, hoverStyle, rowHeight, cellPy, palette, accentColor, ariaRowIndex, handleCheckbox, onRowClick, toggleRowExpansion, onMeasure, }) => {
|
|
30
34
|
// Measured-height virtualization: report this row's real height (main + any
|
|
@@ -63,15 +67,38 @@ const TableRow = React.memo(({ row, rowIndex, isChecked, isExpanded, isContent,
|
|
|
63
67
|
onRowClick(row, { label: header.label, id: header.id });
|
|
64
68
|
}
|
|
65
69
|
}, [row, onRowClick]);
|
|
70
|
+
const variant = useTableVariant();
|
|
66
71
|
const firstDataColIndex = columns.findIndex((c) => !c.isHidden);
|
|
67
72
|
const accentSx = accentColor ? `inset 3px 0 0 ${accentColor}` : undefined;
|
|
73
|
+
// A selected row earns the leading bar only where a group accent isn't already
|
|
74
|
+
// claiming that edge — the group's identity is the scarcer signal.
|
|
75
|
+
const leadSx = variant.row.showSelectedBar && isChecked && !accentColor
|
|
76
|
+
? `inset 3px 0 0 ${variant.row.selectedBarColor}`
|
|
77
|
+
: accentSx;
|
|
78
|
+
const restsOnIndex = variant.slot.rest === "index";
|
|
79
|
+
const rowSx = {
|
|
80
|
+
...(variant.row.hoverScope === "row"
|
|
81
|
+
? { "&:hover > td[data-hoverable='true']": { backgroundColor: variant.row.hoverBg } }
|
|
82
|
+
: {}),
|
|
83
|
+
// opacity, not display: a hidden-by-display checkbox leaves the a11y tree and
|
|
84
|
+
// cannot be tabbed to, so `:focus-within` would never fire to bring it back.
|
|
85
|
+
...(restsOnIndex
|
|
86
|
+
? {
|
|
87
|
+
"& .table-slot-box": { opacity: isChecked ? 1 : 0 },
|
|
88
|
+
"& .table-slot-index": { opacity: isChecked ? 0 : 1 },
|
|
89
|
+
"&:hover .table-slot-box, &:focus-within .table-slot-box": { opacity: 1 },
|
|
90
|
+
"&:hover .table-slot-index, &:focus-within .table-slot-index": { opacity: 0 },
|
|
91
|
+
}
|
|
92
|
+
: {}),
|
|
93
|
+
};
|
|
68
94
|
// Pinned/frozen columns get a tinted, opaque background so the frozen pane reads
|
|
69
95
|
// as one piece with its header (and so sticky cells cover scrolling content).
|
|
70
96
|
const frozenCellBg = freezedBgColor !== null && freezedBgColor !== void 0 ? freezedBgColor : theme.colors.table.hover[100];
|
|
71
97
|
const cellStyles = row.cellStyle;
|
|
72
98
|
const rowStyle = row.rowStyle;
|
|
99
|
+
const chromeHoverable = rowStyle ? "false" : "true";
|
|
73
100
|
const rowContent = getRowContent(row);
|
|
74
|
-
return (_jsxs(React.Fragment, { children: [_jsxs(Tr, { ref: mainRowRef, "aria-rowindex": ariaRowIndex, opacity: isLoading ? 0.4 : 1, pointerEvents: isLoading ? "none" : "auto", transition: "opacity 0.2s", children: [isContent && (_jsx(Td, { w: "6", p: 0, fontSize: 14, background: isChecked ? selectedFrozenBg : frozenCellBg, color: freezedTextColor, position: "sticky", borderBottom: borderStyle, boxShadow:
|
|
101
|
+
return (_jsxs(React.Fragment, { children: [_jsxs(Tr, { ref: mainRowRef, "aria-rowindex": ariaRowIndex, opacity: isLoading ? 0.4 : 1, pointerEvents: isLoading ? "none" : "auto", transition: "opacity 0.2s", sx: rowSx, children: [isContent && (_jsx(Td, { w: "6", p: 0, fontSize: 14, background: isChecked ? selectedFrozenBg : frozenCellBg, color: freezedTextColor, position: "sticky", borderBottom: borderStyle, boxShadow: leadSx, boxSizing: "border-box", "data-hoverable": chromeHoverable, left: "0px", zIndex: 1, className: "columns sticky-columns", children: !!(row === null || row === void 0 ? void 0 : row.content) && (_jsx(IconButton, { "aria-label": isExpanded ? "Collapse row" : "Expand row", color: theme.colors.textMuted, icon: isExpanded ? (_jsx(ChevronDown, { fontSize: 16 })) : (_jsx(ChevronRight, { fontSize: 16 })), _hover: { transform: "scale(1.1)" }, size: "sm", onClick: () => toggleRowExpansion(rowIndex), variant: "ghost" })) })), isCheckbox && (_jsx(Td, { w: variant.slot.width, minW: variant.slot.width, px: variant.slot.centered ? 0 : undefined, textAlign: variant.slot.centered ? "center" : undefined, fontSize: 14, fontWeight: 600, color: theme.colors.background[50], textTransform: "capitalize", background: isChecked ? selectedFrozenBg : frozenCellBg, position: "sticky", borderBottom: borderStyle, boxShadow: !isContent ? leadSx : undefined, "data-hoverable": chromeHoverable, boxSizing: "border-box", left: "0px", zIndex: 1, className: "columns sticky-columns", children: _jsxs(Box, { display: restsOnIndex ? "grid" : undefined, placeItems: "center", children: [restsOnIndex && (_jsx(Box, { as: "span", className: "table-slot-index", gridArea: "1 / 1", color: variant.slot.indexInk, fontSize: "0.6875rem", fontWeight: 500, transition: "opacity 0.15s ease-in-out", sx: { fontVariantNumeric: "tabular-nums" }, children: rowIndex + 1 })), _jsx(Box, { as: "span", className: restsOnIndex ? "table-slot-box" : undefined, gridArea: restsOnIndex ? "1 / 1" : undefined, display: "flex", alignItems: "center", justifyContent: "center", transition: "opacity 0.15s ease-in-out", children: _jsx(CheckBox, { "aria-label": `Select row ${rowIndex + 1}`, onChange: () => handleCheckbox(getRowId(row)), isChecked: isChecked }) })] }) })), columns.map((header, headerIndex) => {
|
|
75
102
|
var _a, _b, _c;
|
|
76
103
|
if (header.isHidden)
|
|
77
104
|
return null;
|
|
@@ -86,13 +113,15 @@ const TableRow = React.memo(({ row, rowIndex, isChecked, isExpanded, isContent,
|
|
|
86
113
|
const statusOnSolid = statusColor
|
|
87
114
|
? (_c = statusColor.onSolid) !== null && _c !== void 0 ? _c : onFilled(statusColor.solid, theme.colors.white, theme.colors.black)
|
|
88
115
|
: undefined;
|
|
89
|
-
|
|
116
|
+
const isBleed = variant.cells.statusFill === "bleed" && !!statusColor;
|
|
117
|
+
const canHover = !isBleed && !((cellStyles === null || cellStyles === void 0 ? void 0 : cellStyles[header.id]) || rowStyle);
|
|
118
|
+
return (_jsx(Td, { maxWidth: 500, minWidth: 120, height: `${rowHeight}px`, py: isBleed ? 0 : cellPy, px: isBleed ? 0 : undefined, onClick: () => handleCellClick(header), fontSize: 14, fontWeight: 400, position: isFrozen ? "sticky" : undefined, left: isFrozen ? leftOffsets[headerIndex] : undefined, zIndex: isFrozen ? 1 : 0, background: isBleed ? statusColor.solid : isChecked ? (isFrozen ? selectedFrozenBg : selectedBg) : isFrozen ? frozenCellBg : theme.colors.background[50], textOverflow: "ellipsis", boxShadow: isFirstDataCell ? leadSx : undefined, borderBottom: noBorders
|
|
90
119
|
? "none"
|
|
91
|
-
: `0.063rem solid ${
|
|
120
|
+
: `0.063rem solid ${isFrozen || isChecked
|
|
121
|
+
? variant.row.frozenRuleColor
|
|
122
|
+
: variant.row.ruleColor}`, className: `columns ${isFrozen ? "sticky-columns" : "scrollable-columns"}`, boxSizing: "border-box", color: isBleed ? statusOnSolid : variant.cells.ink, "data-hoverable": canHover ? "true" : "false", _hover: variant.row.hoverScope === "row" || !canHover
|
|
92
123
|
? EMPTY_HOVER
|
|
93
|
-
: (
|
|
94
|
-
? EMPTY_HOVER
|
|
95
|
-
: hoverStyle, children: isStatus && statusColor ? (_jsx(StatusCell, { value: normalizeTableCellValue(row[header.id]), onSolid: statusOnSolid })) : (_jsx(Box, { display: "block", overflow: "hidden", whiteSpace: "normal", overflowWrap: "break-word", children: normalizeTableCellValue(header.node ? header.node(row) : row[header.id]) })) }, headerIndex + 1));
|
|
124
|
+
: hoverStyle, children: isBleed ? (_jsx(StatusCell, { value: normalizeTableCellValue(row[header.id]), onSolid: statusOnSolid })) : isStatus && statusColor ? (_jsx(StatusPill, { value: normalizeTableCellValue(row[header.id]), soft: statusColor.soft, ink: resolvePillInk(statusColor.text, statusColor.soft, theme.colors.background[50]), radius: variant.cells.pillRadius })) : (_jsx(Box, { display: "block", overflow: "hidden", whiteSpace: "normal", overflowWrap: "break-word", children: normalizeTableCellValue(header.node ? header.node(row) : row[header.id]) })) }, headerIndex + 1));
|
|
96
125
|
}), isLink && (_jsx(Td, { w: 2, p: 0, fontSize: 14, background: isChecked ? (isActionFreeze ? selectedFrozenBg : selectedBg) : isActionFreeze ? frozenCellBg : theme.colors.background[50], color: freezedTextColor, position: isActionFreeze ? "sticky" : "relative", borderBottom: borderStyle, boxSizing: "border-box", right: 0, zIndex: 1, className: `columns sticky-columns${isActionFreeze ? "-right" : ""}`, children: (row.onLink || row.onEdit || row.onDelete) ? (_jsx(TableActions, { row: row })) : null }))] }), rowContent && isExpanded && (_jsx(Tr, { ref: expandedRowRef, children: _jsx(Td, { colSpan: columns.length +
|
|
97
126
|
(isCheckbox ? 1 : 0) +
|
|
98
127
|
(isContent ? 1 : 0) +
|
|
@@ -101,6 +130,7 @@ const TableRow = React.memo(({ row, rowIndex, isChecked, isExpanded, isContent,
|
|
|
101
130
|
const TableBody = ({ data, isCheckbox, columns, startRow, columnWidths, freezedBgColor, freezedTextColor, noBorders, handleCheckbox, selections, isLoading, onRowClick, isContent, isLink, isActionFreeze, loadingSkeletonRows, scrollContainerRef, density, accentColors, groups, onAddItem, emptyState, }) => {
|
|
102
131
|
var _a, _b, _c;
|
|
103
132
|
const theme = useCustomTheme();
|
|
133
|
+
const variant = useTableVariant();
|
|
104
134
|
const [expandedRows, setExpandedRows] = useState(new Set());
|
|
105
135
|
const [collapsedGroups, setCollapsedGroups] = useState(new Set());
|
|
106
136
|
const toggleGroup = useCallback((value) => {
|
|
@@ -246,17 +276,16 @@ const TableBody = ({ data, isCheckbox, columns, startRow, columnWidths, freezedB
|
|
|
246
276
|
const checkboxOffset = isCheckbox ? 50 : 0;
|
|
247
277
|
return columnWidths.map((_, idx) => columnWidths.slice(0, idx).reduce((sum, w) => sum + w, 0) + checkboxOffset);
|
|
248
278
|
}, [columnWidths, isCheckbox]);
|
|
249
|
-
const borderStyle = useMemo(() => noBorders ? "none" : `0.063rem solid ${
|
|
279
|
+
const borderStyle = useMemo(() => noBorders ? "none" : `0.063rem solid ${variant.row.ruleColor}`, [noBorders, variant.row.ruleColor]);
|
|
250
280
|
// Selected-row tint applied per-cell (NOT a blanket `& td` override) so status
|
|
251
281
|
// cells keep their solid color + white text instead of white-on-tint.
|
|
252
|
-
const selectedBg =
|
|
282
|
+
const selectedBg = variant.row.selectedBg;
|
|
253
283
|
// Sticky/frozen cells overlay scrolling content, so their selected background
|
|
254
284
|
// must be OPAQUE — paint the (translucent) tint over an opaque base.
|
|
255
285
|
const selectedFrozenBg = `linear-gradient(0deg, ${selectedBg}, ${selectedBg}), ${theme.colors.background[50]}`;
|
|
256
286
|
// Dark mode lifts the hover fill to `table.hover[500]`; `[300]` sits ~1.2:1 from the canvas.
|
|
257
287
|
// No ink flip needed — see `tableRowHoverStyle.ts`.
|
|
258
|
-
const
|
|
259
|
-
const hoverStyle = useMemo(() => getTableRowHoverStyle(theme.colors, isDark), [theme.colors, isDark]);
|
|
288
|
+
const hoverStyle = useMemo(() => ({ backgroundColor: variant.row.hoverBg }), [variant.row.hoverBg]);
|
|
260
289
|
// Flatten groups → one sequence of header/row items so it can be windowed.
|
|
261
290
|
// Independent of scrollTop, so scrolling reuses it instead of re-flattening.
|
|
262
291
|
const groupItems = useMemo(() => {
|
|
@@ -7,6 +7,7 @@ import { accentTextOnCanvas } from "../../../Theme/tokens/builders/accentText.js
|
|
|
7
7
|
import TableFilters from "../filters/TableFilters.js";
|
|
8
8
|
import { ChevronDown, ChevronsUpDown, ChevronUp } from "lucide-react";
|
|
9
9
|
import CheckBox from "../../Checkbox/Checkbox.js";
|
|
10
|
+
import { useTableVariant } from "../variants/TableVariantContext.js";
|
|
10
11
|
const TableHeader = ({ columns, isCheckbox, handleSort, headerRefs, columnWidths, columnsSort, headerBgColor, freezedBgColor, freezedTextColor, noBorders, handleCheckbox, checked, isLoading, isContent, isLink, isActionFreeze, setColumnsSearch, columnsSearch, isSelecting, }) => {
|
|
11
12
|
const [openFilterId, setOpenFilterId] = useState(null);
|
|
12
13
|
return (_jsxs(Tr, { pr: 0, "aria-rowindex": 1, children: [isContent && _jsx(ContentSpacerCell, { noBorders: noBorders }), isCheckbox && (_jsx(SelectAllCell, { freezedTextColor: freezedTextColor, noBorders: noBorders, isSelecting: isSelecting, isLoading: isLoading, checked: checked, handleCheckbox: handleCheckbox })), columns.map((header, index) => {
|
|
@@ -18,30 +19,33 @@ const TableHeader = ({ columns, isCheckbox, handleSort, headerRefs, columnWidths
|
|
|
18
19
|
export default memo(TableHeader);
|
|
19
20
|
const SelectAllCell = memo(({ freezedTextColor, noBorders, isSelecting, isLoading, checked, handleCheckbox, }) => {
|
|
20
21
|
const theme = useCustomTheme();
|
|
21
|
-
|
|
22
|
+
const variant = useTableVariant();
|
|
23
|
+
return (_jsx(Th, { scope: "col", w: variant.slot.width, minW: variant.slot.width, px: variant.slot.centered ? 0 : undefined, textAlign: variant.slot.centered ? "center" : undefined, fontSize: 14, fontWeight: 600, color: freezedTextColor, textTransform: "capitalize", backgroundColor: variant.header.bg, position: "sticky", className: `columns sticky-columns`, left: "0px", zIndex: 9, borderBottom: noBorders ? "none" : `0.063rem solid ${variant.header.ruleColor}`, children: _jsx(Box, { display: "flex", alignItems: "center", justifyContent: variant.slot.centered ? "center" : "flex-start", children: isSelecting ? (_jsx(Spinner, { size: "sm", color: theme.colors.accentText })) : (_jsx(CheckBox, { "aria-label": "Select all rows", variant: "outline", onChange: () => handleCheckbox(0), isChecked: isLoading ? false : checked === true, isIndeterminate: checked === "indeterminate" })) }) }));
|
|
22
24
|
});
|
|
23
25
|
const ContentSpacerCell = memo(({ noBorders }) => {
|
|
24
|
-
const
|
|
25
|
-
return (_jsx(Th, { scope: "col", w: 6, minW: "35px", p: 0, backgroundColor:
|
|
26
|
+
const variant = useTableVariant();
|
|
27
|
+
return (_jsx(Th, { scope: "col", w: 6, minW: "35px", p: 0, backgroundColor: variant.header.bg, borderBottom: noBorders ? "none" : `0.063rem solid ${variant.header.ruleColor}`, position: "sticky", className: `columns sticky-columns`, left: "0px", zIndex: 1 }));
|
|
26
28
|
});
|
|
27
29
|
const ViewSpacerCell = memo(({ noBorders, isActionFreeze, }) => {
|
|
28
|
-
const
|
|
29
|
-
return (_jsx(Th, { scope: "col", w: 2, p: 0, minW: "2.065rem", backgroundColor:
|
|
30
|
+
const variant = useTableVariant();
|
|
31
|
+
return (_jsx(Th, { scope: "col", w: 2, p: 0, minW: "2.065rem", backgroundColor: variant.header.bg, borderBottom: noBorders ? "none" : `0.063rem solid ${variant.header.ruleColor}`, position: isActionFreeze ? "sticky" : "relative", className: `columns sticky-columns`, right: "0px", zIndex: 1 }));
|
|
30
32
|
});
|
|
31
33
|
const SortingIcon = memo(({ label, sortState, isVisible, handleSortClick, }) => {
|
|
32
34
|
const theme = useCustomTheme();
|
|
35
|
+
const variant = useTableVariant();
|
|
33
36
|
return (_jsxs(Box, { as: "button", type: "button", "aria-label": `Sort by ${label}`, display: "inline-flex", alignItems: "center", justifyContent: "center", cursor: "pointer", ml: 2, p: 0, border: "none", bg: "transparent", lineHeight: "1", onClick: handleSortClick, transition: "color 0.2s ease-in-out, opacity 0.2s ease-in-out",
|
|
34
37
|
// Kept out of view until hover/focus so the header looks exactly as it did,
|
|
35
38
|
// while staying in the DOM and reachable by Tab.
|
|
36
39
|
opacity: isVisible ? 1 : 0, _focus: { opacity: 1 }, _focusVisible: { opacity: 1 }, color: theme.colors.textMuted, _hover: {
|
|
37
40
|
opacity: 1,
|
|
38
|
-
color: accentTextOnCanvas(theme.colors.secondary,
|
|
41
|
+
color: accentTextOnCanvas(theme.colors.secondary, variant.header.bg),
|
|
39
42
|
}, children: [sortState === "none" && _jsx(ChevronsUpDown, { size: 14 }), sortState === "asc" && _jsx(ChevronUp, { size: 14 }), sortState === "desc" && _jsx(ChevronDown, { size: 14 })] }));
|
|
40
43
|
});
|
|
41
44
|
const ColumnHeader = memo(({ header, index, columnWidths, isCheckbox, noBorders, columnsSort, headerRefs, columnsSearch, setColumnsSearch, handleSort, openFilterId, setOpenFilterId, }) => {
|
|
42
45
|
var _a;
|
|
43
46
|
const [isHovered, setIsHovered] = useState(false);
|
|
44
47
|
const theme = useCustomTheme();
|
|
48
|
+
const variant = useTableVariant();
|
|
45
49
|
const isFrozen = header.isFreeze;
|
|
46
50
|
const leftOffset = isFrozen
|
|
47
51
|
? calculateLeftOffset(columnWidths, index) + (isCheckbox ? 50 : 0)
|
|
@@ -77,7 +81,16 @@ const ColumnHeader = memo(({ header, index, columnWidths, isCheckbox, noBorders,
|
|
|
77
81
|
document.addEventListener("mouseup", onMouseUp);
|
|
78
82
|
};
|
|
79
83
|
const isSortActive = !!(isSorting === null || isSorting === void 0 ? void 0 : isSorting.direction) && isSorting.direction !== "none";
|
|
80
|
-
|
|
84
|
+
// Studio keeps the kebab out of the resting header — nine of them read louder than
|
|
85
|
+
// the labels. A column that is filtering or sorting keeps its control on show.
|
|
86
|
+
const showActions = variant.header.actions === "always" ||
|
|
87
|
+
isHovered ||
|
|
88
|
+
isSortActive ||
|
|
89
|
+
openFilterId === header.id ||
|
|
90
|
+
!!columnsSearch[header.id];
|
|
91
|
+
return (_jsx(Th, { scope: "col", ref: (el) => (headerRefs.current[index] = el), "aria-sort": ariaSort, textTransform: variant.header.textTransform, fontSize: variant.header.fontSize, fontWeight: variant.header.fontWeight, letterSpacing: variant.header.letterSpacing, position: isFrozen ? "sticky" : undefined, left: isFrozen ? leftOffset : undefined, minWidth: 120, backgroundColor: variant.header.bg, maxWidth: 500, zIndex: isFrozen ? 2 : 1, py: 2, pr: 0, overflow: "hidden", borderTop: "none", borderBottom: noBorders ? "none" : `0.063rem solid ${variant.header.ruleColor}`, borderRight: noBorders || !variant.header.showColumnRule
|
|
92
|
+
? "none"
|
|
93
|
+
: `0.063rem solid ${variant.header.ruleColor}`, className: `columns ${isFrozen ? "sticky-columns" : "scrollable-columns"}`, height: variant.header.height, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: _jsxs(Box, { display: "flex", color: variant.header.ink, lineHeight: "1.25rem", justifyContent: "space-between", alignItems: "center", position: "relative", children: [_jsx(Box, { textOverflow: "ellipsis", whiteSpace: "nowrap", display: "inline-block", overflow: "hidden", children: header.label }), _jsxs(Box, { display: "inline-flex", alignItems: "center", opacity: showActions ? 1 : 0, transition: "opacity 0.2s ease-in-out", _focusWithin: { opacity: 1 }, children: [header.isSort && (_jsx(SortingIcon, { label: String(header.label), sortState: (_a = isSorting === null || isSorting === void 0 ? void 0 : isSorting.direction) !== null && _a !== void 0 ? _a : "none", isVisible: isHovered || isSortActive, handleSortClick: () => {
|
|
81
94
|
let direction = "asc";
|
|
82
95
|
if ((isSorting === null || isSorting === void 0 ? void 0 : isSorting.direction) === "asc") {
|
|
83
96
|
direction = "desc";
|
|
@@ -86,7 +99,7 @@ const ColumnHeader = memo(({ header, index, columnWidths, isCheckbox, noBorders,
|
|
|
86
99
|
direction = "none";
|
|
87
100
|
}
|
|
88
101
|
handleSort(header.id, direction);
|
|
89
|
-
} })), sortPriority > 0 && (_jsx(Box, { as: "span", ml: 1, fontSize: "0.625rem", fontWeight: 700, lineHeight: "1", borderRadius: "full", px: "0.3rem", py: "0.1rem", bg: theme.colors.primary.opacity[16], color: accentTextOnCanvas(theme.colors.primary,
|
|
102
|
+
} })), sortPriority > 0 && (_jsx(Box, { as: "span", ml: 1, fontSize: "0.625rem", fontWeight: 700, lineHeight: "1", borderRadius: "full", px: "0.3rem", py: "0.1rem", bg: theme.colors.primary.opacity[16], color: accentTextOnCanvas(theme.colors.primary, variant.header.bg), children: sortPriority })), _jsx(TableFilters, { header: header, setColumnsSearch: (searchVal) => setColumnsSearch((prev) => ({
|
|
90
103
|
...prev,
|
|
91
104
|
[header.id]: searchVal,
|
|
92
105
|
})), columnsSearch: columnsSearch[header.id] || "", onClose: () => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createContext, useContext, useMemo } from "react";
|
|
2
|
+
import { useCustomTheme } from "../../../Theme/useCustomTheme.js";
|
|
3
|
+
import { isDarkCanvas } from "../../../Theme/tokens/builders/accentText.js";
|
|
4
|
+
import { classicPreset } from "./classic.js";
|
|
5
|
+
const TableVariantContext = createContext(null);
|
|
6
|
+
export const TableVariantProvider = TableVariantContext.Provider;
|
|
7
|
+
/** No provider means the table as it always was — the default is a variant, not a gap. */
|
|
8
|
+
export function useTableVariant() {
|
|
9
|
+
const provided = useContext(TableVariantContext);
|
|
10
|
+
const theme = useCustomTheme();
|
|
11
|
+
const isDark = isDarkCanvas(theme.colors.backgroundColor.main);
|
|
12
|
+
return useMemo(() => provided !== null && provided !== void 0 ? provided : classicPreset(theme.colors, isDark), [provided, theme.colors, isDark]);
|
|
13
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { accentTextOnCanvas } from "../../../Theme/tokens/builders/accentText.js";
|
|
2
|
+
import { getTableRowHoverStyle } from "../components/tableRowHoverStyle.js";
|
|
3
|
+
/**
|
|
4
|
+
* The table as it shipped. Pinned by snapshot: every value here is read off the
|
|
5
|
+
* live component, so adding a variant cannot move it.
|
|
6
|
+
*/
|
|
7
|
+
export const classicPreset = (colors, isDark) => {
|
|
8
|
+
const headerBg = colors.table.hover[200];
|
|
9
|
+
return {
|
|
10
|
+
header: {
|
|
11
|
+
bg: headerBg,
|
|
12
|
+
ink: accentTextOnCanvas(colors.secondary, headerBg),
|
|
13
|
+
fontSize: 13,
|
|
14
|
+
fontWeight: 600,
|
|
15
|
+
textTransform: "capitalize",
|
|
16
|
+
letterSpacing: "normal",
|
|
17
|
+
height: "45px",
|
|
18
|
+
ruleColor: colors.boxborder[200],
|
|
19
|
+
showColumnRule: true,
|
|
20
|
+
actions: "always",
|
|
21
|
+
},
|
|
22
|
+
row: {
|
|
23
|
+
hoverBg: getTableRowHoverStyle(colors, isDark).backgroundColor,
|
|
24
|
+
hoverScope: "cell",
|
|
25
|
+
ruleColor: colors.boxborder[200],
|
|
26
|
+
frozenRuleColor: colors.boxborder[300],
|
|
27
|
+
selectedBg: colors.primary.opacity[16],
|
|
28
|
+
selectedBarColor: colors.primary[500],
|
|
29
|
+
showSelectedBar: false,
|
|
30
|
+
},
|
|
31
|
+
slot: {
|
|
32
|
+
width: "6",
|
|
33
|
+
rest: "checkbox",
|
|
34
|
+
indexInk: colors.textMuted,
|
|
35
|
+
centered: false,
|
|
36
|
+
},
|
|
37
|
+
cells: {
|
|
38
|
+
ink: colors.text[500],
|
|
39
|
+
statusFill: "bleed",
|
|
40
|
+
pillRadius: "0",
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { classicPreset } from "./classic.js";
|
|
2
|
+
import { studioPreset } from "./studio.js";
|
|
3
|
+
/** Adding a variant is one file and one union member — no component changes. */
|
|
4
|
+
export const TABLE_VARIANTS = {
|
|
5
|
+
classic: classicPreset,
|
|
6
|
+
studio: studioPreset,
|
|
7
|
+
};
|
|
8
|
+
export * from "./tokens.js";
|
|
9
|
+
export { classicPreset, studioPreset };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AA_NORMAL_TEXT } from "../../../Theme/tokens/builders/accentText.js";
|
|
2
|
+
import { compositeOver } from "../../../Theme/tokens/builders/color.js";
|
|
3
|
+
import { liftToContrast } from "../../../Theme/tokens/builders/outlineRung.js";
|
|
4
|
+
const cache = new Map();
|
|
5
|
+
/**
|
|
6
|
+
* A consumer `statusColors` hex is a FILL, and `pickTableColor` hands it straight back as ink
|
|
7
|
+
* over a 13%-alpha tint of itself — legible reversed out of a solid cell, ~1.9:1 on a pill.
|
|
8
|
+
* The palette path is already resolved by `resolveStatusTone`; this rescues the override path.
|
|
9
|
+
*/
|
|
10
|
+
export function resolvePillInk(ink, soft, surface) {
|
|
11
|
+
const key = `${ink}|${soft}|${surface}`;
|
|
12
|
+
const hit = cache.get(key);
|
|
13
|
+
if (hit !== undefined)
|
|
14
|
+
return hit;
|
|
15
|
+
const resolved = liftToContrast(ink, compositeOver(soft, surface), AA_NORMAL_TEXT);
|
|
16
|
+
cache.set(key, resolved);
|
|
17
|
+
return resolved;
|
|
18
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { CHROME_RULE, MIN_PERCEPTIBLE_STEP, liftToContrast, } from "../../../Theme/tokens/builders/outlineRung.js";
|
|
2
|
+
import { getTableRowHoverStyle } from "../components/tableRowHoverStyle.js";
|
|
3
|
+
/**
|
|
4
|
+
* Quieter chrome, one rule instead of a grid, and a slot that rests on the row
|
|
5
|
+
* number. Every colour is lifted against the surface it actually sits on.
|
|
6
|
+
*/
|
|
7
|
+
export const studioPreset = (colors, isDark) => {
|
|
8
|
+
const surface = colors.background[50];
|
|
9
|
+
// Studio drops the per-column rule, so the one line left has to be visible on
|
|
10
|
+
// every brand — `boxborder[200]` measures as low as 1.09:1 on some of them.
|
|
11
|
+
const rule = liftToContrast(colors.boxborder[200], surface, CHROME_RULE);
|
|
12
|
+
return {
|
|
13
|
+
header: {
|
|
14
|
+
bg: surface,
|
|
15
|
+
ink: colors.text[500],
|
|
16
|
+
fontSize: 11,
|
|
17
|
+
fontWeight: 600,
|
|
18
|
+
textTransform: "uppercase",
|
|
19
|
+
letterSpacing: "0.06em",
|
|
20
|
+
height: "40px",
|
|
21
|
+
ruleColor: rule,
|
|
22
|
+
showColumnRule: false,
|
|
23
|
+
actions: "hover",
|
|
24
|
+
},
|
|
25
|
+
row: {
|
|
26
|
+
hoverBg: getTableRowHoverStyle(colors, isDark).backgroundColor,
|
|
27
|
+
hoverScope: "row",
|
|
28
|
+
ruleColor: rule,
|
|
29
|
+
frozenRuleColor: rule,
|
|
30
|
+
selectedBg: liftToContrast(colors.primary[50], surface, MIN_PERCEPTIBLE_STEP),
|
|
31
|
+
selectedBarColor: colors.primary[500],
|
|
32
|
+
showSelectedBar: true,
|
|
33
|
+
},
|
|
34
|
+
slot: {
|
|
35
|
+
width: "3.5rem",
|
|
36
|
+
rest: "index",
|
|
37
|
+
indexInk: colors.textMuted,
|
|
38
|
+
centered: true,
|
|
39
|
+
},
|
|
40
|
+
cells: {
|
|
41
|
+
ink: colors.text[500],
|
|
42
|
+
statusFill: "pill",
|
|
43
|
+
pillRadius: "0.375rem",
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -124,7 +124,7 @@ export type { PlanBadgeInput, PlanBadgeResult } from "./Utils/planBadge";
|
|
|
124
124
|
export type { PlanExpiryInput } from "./Utils/planExpiry";
|
|
125
125
|
export type { LimitReachedModalProps, LimitKind, } from "./Components/LimitReachedModal/LimitReachedModalProps";
|
|
126
126
|
export type { AccountHandoffConfig, AccountHandoff, AccountHandoffLinkOptions, AccountHandoffUsersOptions, ResolveReturnUrlOptions, } from "./Utils/accountHandoff";
|
|
127
|
-
export type { TableProps, TableHeaderProps, TableColumnType, TableDensity, TableEmptyState, TableRenderGroup, HeaderActionsProps, ColumnSortingProps, ExportOption, DataObject, FilterValues, } from "./Components/Table/TableProps";
|
|
127
|
+
export type { TableProps, TableHeaderProps, TableColumnType, TableDensity, TableVariant, TableEmptyState, TableRenderGroup, HeaderActionsProps, ColumnSortingProps, ExportOption, DataObject, FilterValues, } from "./Components/Table/TableProps";
|
|
128
128
|
export type { ButtonProps } from "./Components/Button/ButtonProps";
|
|
129
129
|
export type { CardProps } from "./Components/Card/CardProps";
|
|
130
130
|
export type { ProfileCardProps, ProfileCardVariant, ProfileCardVariantLegacy, } from "./Components/ProfileCard/ProfileCardProps";
|
package/package.json
CHANGED