Skip to content

Commit e8dd424

Browse files
authored
Merge pull request #44 from outshift-open/feat-table-column-helper
feat: optional tooltip helper for table column headers
2 parents 68174f3 + ecac1a2 commit e8dd424

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

packages/open-ui-kit/src/components/table/components/table.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { TableProps } from "../types";
3232
import { tableComfortStyles, tableCompactStyles } from "../styles";
3333
import { Box, PaginationItem, SvgIconProps, useTheme } from "@mui/material";
3434
import { EmptyState, Link, OverflowTooltip, TooltipSize } from "@/components";
35+
import { withHeaderHelpTooltips } from "../utils/helpers";
3536

3637
/**
3738
* `Table` Component
@@ -109,7 +110,7 @@ export const CreateTableInstance = <TData extends MRT_RowData>({
109110
enableFilters: !!data.length,
110111
enableFullScreenToggle: !!data.length,
111112
enableHiding: !!data.length,
112-
columns,
113+
columns: withHeaderHelpTooltips(columns),
113114
data,
114115
enableColumnActions: false,
115116
enableTopToolbar,

packages/open-ui-kit/src/components/table/stories/table.stories.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,18 +118,21 @@ const data = {
118118
accessorKey: "id",
119119
header: "ID",
120120
size: 350,
121+
meta: { headerTooltip: "The unique identifier of the record" },
121122
},
122123
{
123124
header: "Name",
124125
accessorKey: "name",
125126
enableColumnOrdering: false,
126127
size: 200,
128+
meta: { headerTooltip: "Full name of the person" },
127129
},
128130
{
129131
header: "Phone",
130132
accessorKey: "phone",
131133
enableSorting: false,
132134
enableColumnOrdering: false,
135+
meta: { headerTooltip: "Primary phone number" },
133136
},
134137
{
135138
header: "firstName",

packages/open-ui-kit/src/components/table/types/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,16 @@ interface TableRow {
6868
subRows?: ReactNode;
6969
}
7070

71+
interface HeaderTooltipMeta {
72+
headerTooltip?: ReactNode;
73+
}
74+
7175
export {
7276
AtomicTypes,
7377
ExportProps,
7478
TableProps,
7579
TableRow,
7680
TopToolbarProps,
7781
TableTitle,
82+
HeaderTooltipMeta,
7883
};

packages/open-ui-kit/src/components/table/utils/helpers.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66

77
import {
88
MRT_Column,
9+
MRT_ColumnDef,
910
MRT_RowData,
1011
MRT_TableInstance,
1112
} from "material-react-table";
13+
import { Box, IconButton, Stack } from "@mui/material";
14+
import { Tooltip, TooltipSize } from "@/components";
15+
import { InfoCircleOutline } from "@/custom-icons";
16+
import { HeaderTooltipMeta } from "../types";
1217

1318
// Check rightmost left-pinned column / leftmost right-pinned column
1419
export const isOuterPinnedColumn = <TData extends MRT_RowData>(
@@ -38,3 +43,49 @@ export const parseFromValuesOrFunc = <T, U>(
3843
fn: ((arg: U) => T) | T | undefined,
3944
arg: U,
4045
): T | undefined => (fn instanceof Function ? fn(arg) : fn);
46+
47+
// Enhance column headers to optionally show an info tooltip icon.
48+
// Usage: column.meta?.headerTooltip?: React.ReactNode
49+
export const withHeaderHelpTooltips = <
50+
TData extends MRT_RowData,
51+
TValue = unknown,
52+
>(
53+
columns: MRT_ColumnDef<TData, TValue>[],
54+
): MRT_ColumnDef<TData, TValue>[] => {
55+
return columns.map((col) => {
56+
const meta = col.meta as HeaderTooltipMeta;
57+
const hasHeaderTooltip =
58+
meta?.headerTooltip !== undefined && meta?.headerTooltip !== null;
59+
60+
const updated: MRT_ColumnDef<TData, TValue> = {
61+
...col,
62+
};
63+
64+
if (hasHeaderTooltip) {
65+
updated.Header = (
66+
<Stack direction="row" alignItems="flex-start" gap="2px">
67+
<Box component="span">{col.header}</Box>
68+
<Tooltip
69+
size={TooltipSize.Medium}
70+
title={meta?.headerTooltip}
71+
placement="top"
72+
>
73+
<IconButton
74+
sx={{
75+
color: (theme) => theme.palette.vars.controlIconDefault,
76+
"&:hover": {
77+
color: (theme) => theme.palette.vars.controlIconHover,
78+
},
79+
}}
80+
aria-label="Column info"
81+
>
82+
<InfoCircleOutline sx={{ width: "16px", height: "16px" }} />
83+
</IconButton>
84+
</Tooltip>
85+
</Stack>
86+
);
87+
}
88+
89+
return updated;
90+
});
91+
};

0 commit comments

Comments
 (0)