Skip to content

Commit

Permalink
Merge pull request #429 from laratran/add-enable-cell-hover-reveal
Browse files Browse the repository at this point in the history
Add enableCellHoverReveal column option
  • Loading branch information
alessandrojcm authored Dec 13, 2024
2 parents 508659c + 5999ffd commit 0eb109c
Show file tree
Hide file tree
Showing 7 changed files with 6,012 additions and 4,696 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,17 @@ export const columnOptions: ColumnOption[] = [
required: false,
type: "'select' | 'text' | 'multi-select'",
},
{
columnOption: 'enableCellHoverReveal',
defaultValue: '',
description:
"Enable or disable cell hover reveal for this column. There are some limitations to this feature. Passing props through mantineTableBodyCellProps might not work as expected. For example, passing align:'right' to mantineTableBodyCellProps would not be applied.",
link: '',
linkText: '',
source: 'MRT',
required: false,
type: 'boolean',
},
{
columnOption: 'enableClickToCopy',
defaultValue: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,34 @@
outline: 1px solid var(--mantine-color-gray-7);
}
}

.root-cell-hover-reveal {
overflow: visible;
}

.cell-hover-reveal {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: var(--mrt-cell-align);
}

.cell-hover-reveal.overflowing:hover{
overflow: visible;
white-space: normal;
position: absolute;
z-index: 2;
padding: var(--table-vertical-spacing)
var(--table-horizontal-spacing, var(--mantine-spacing-xs));
background-color: var(--mrt-base-background-color);
box-shadow: var(--mantine-shadow-sm);
border: 1px solid var(--mantine-primary-color-filled);
text-indent: -1px;
width: max-content;
top: 0;
left: 0;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
118 changes: 87 additions & 31 deletions packages/mantine-react-table/src/components/body/MRT_TableBodyCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
type MouseEvent,
type RefObject,
useEffect,
useRef,
useState,
} from 'react';

Expand Down Expand Up @@ -194,6 +195,64 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
table,
};

const cellHoverRevealDivRef = useRef<any>(null);
const [isCellContentOverflowing, setIsCellContentOverflowing] =
useState(false);

const onMouseEnter = () => {
if (!columnDef.enableCellHoverReveal) return;
const div = cellHoverRevealDivRef.current;
if (div) {
const isOverflow = div.scrollWidth > div.clientWidth;
setIsCellContentOverflowing(isOverflow);
}
};

const onMouseLeave = () => {
if (!columnDef.enableCellHoverReveal) return;
setIsCellContentOverflowing(false);
};

const renderCellContent = () => {
if (cell.getIsPlaceholder()) {
return columnDef.PlaceholderCell?.({ cell, column, row, table }) ?? null;
}

if (showSkeletons !== false && (isLoading || showSkeletons)) {
return <Skeleton height={20} width={skeletonWidth} {...skeletonProps} />;
}

if (
columnDefType === 'display' &&
(['mrt-row-expand', 'mrt-row-numbers', 'mrt-row-select'].includes(
column.id,
) ||
!row.getIsGrouped())
) {
return columnDef.Cell?.({
column,
renderedCellValue: cell.renderValue() as any,
row,
rowRef,
...cellValueProps,
});
}

if (isCreating || isEditing) {
return <MRT_EditCellTextInput cell={cell} table={table} />;
}

if (showClickToCopyButton && columnDef.enableClickToCopy !== false) {
return (
<MRT_CopyButton cell={cell} table={table}>
<MRT_TableBodyCellValue {...cellValueProps} />
</MRT_CopyButton>
);
}

return <MRT_TableBodyCellValue {...cellValueProps} />;
};

return (
<TableTd
data-column-pinned={isColumnPinned || undefined}
Expand Down Expand Up @@ -243,47 +302,44 @@ export const MRT_TableBodyCell = <TData extends MRT_RowData>({
classes['root-editable-hover'],
columnDefType === 'data' && classes['root-data-col'],
density === 'xs' && classes['root-nowrap'],
columnDef.enableCellHoverReveal && classes['root-cell-hover-reveal'],
tableCellProps?.className,
)}
onDoubleClick={handleDoubleClick}
onDragEnter={handleDragEnter}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
style={(theme) => ({
...widthStyles,
...parseFromValuesOrFunc(tableCellProps.style, theme),
})}
>
{tableCellProps.children ?? (
<>
{cell.getIsPlaceholder() ? (
(columnDef.PlaceholderCell?.({ cell, column, row, table }) ?? null)
) : showSkeletons !== false && (isLoading || showSkeletons) ? (
<Skeleton height={20} width={skeletonWidth} {...skeletonProps} />
) : columnDefType === 'display' &&
(['mrt-row-expand', 'mrt-row-numbers', 'mrt-row-select'].includes(
column.id,
) ||
!row.getIsGrouped()) ? (
columnDef.Cell?.({
column,
renderedCellValue: cell.renderValue() as any,
row,
rowRef,
...cellValueProps,
})
) : isCreating || isEditing ? (
<MRT_EditCellTextInput cell={cell} table={table} />
) : showClickToCopyButton && columnDef.enableClickToCopy !== false ? (
<MRT_CopyButton cell={cell} table={table}>
<MRT_TableBodyCellValue {...cellValueProps} />
</MRT_CopyButton>
<>
{tableCellProps.children ??
(columnDef.enableCellHoverReveal ? (
<div
className={clsx(
columnDef.enableCellHoverReveal &&
!(isCreating || isEditing) &&
classes['cell-hover-reveal'],
isCellContentOverflowing && classes['overflowing'],
)}
ref={cellHoverRevealDivRef}
>
{renderCellContent()}
{cell.getIsGrouped() && !columnDef.GroupedCell && (
<> ({row.subRows?.length})</>
)}
</div>
) : (
<MRT_TableBodyCellValue {...cellValueProps} />
)}
{cell.getIsGrouped() && !columnDef.GroupedCell && (
<> ({row.subRows?.length})</>
)}
</>
)}
<>
{renderCellContent()}
{cell.getIsGrouped() && !columnDef.GroupedCell && (
<> ({row.subRows?.length})</>
)}
</>
))}
</>
</TableTd>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const MRT_GlobalFilterTextInput = <TData extends MRT_RowData>({
localization,
mantineSearchTextInputProps,
manualFiltering,
positionGlobalFilter
positionGlobalFilter,
},
refs: { searchInputRef },
setGlobalFilter,
Expand Down
1 change: 1 addition & 0 deletions packages/mantine-react-table/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ export type MRT_ColumnDef<TData extends MRT_RowData, TValue = unknown> = {
table: MRT_TableInstance<TData>;
}) => ReactNode;
editVariant?: 'multi-select' | 'select' | 'text';
enableCellHoverReveal?: boolean;
enableClickToCopy?: ((cell: MRT_Cell<TData>) => boolean) | boolean;
enableColumnActions?: boolean;
enableColumnDragging?: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { MantineReactTable, type MRT_ColumnDef } from '../../src';

import { faker } from '@faker-js/faker';
import { type Meta } from '@storybook/react';

const meta: Meta = {
title: 'Features/Cell Hover Reveal Examples',
};

export default meta;

const columns: MRT_ColumnDef<(typeof data)[0]>[] = [
{
accessorKey: 'firstName',
header: 'First Name',
},
{
accessorKey: 'lastName',
header: 'Last Name',
},
{
accessorKey: 'address',
header: 'Address',
},
{
accessorKey: 'state',
header: 'State',
},
{
accessorKey: 'phoneNumber',
header: 'Phone Number',
},
{
accessorKey: 'job',
enableCellHoverReveal: true,
header: 'Job',
size: 75,
},
{
accessorKey: 'jobDescriptor',
header: 'Job Descriptor',
},
{
accessorKey: 'company',
header: 'Company',
},
];

const data = [...Array(100)].map(() => ({
address: faker.location.streetAddress(),
company: faker.company.name(),
firstName: faker.person.firstName(),
job: faker.person.jobTitle(),
jobDescriptor: faker.person.jobDescriptor(),
lastName: faker.person.lastName(),
phoneNumber: faker.phone.number(),
state: faker.location.state(),
}));

export const CellHoverReveal = () => (
<MantineReactTable columns={columns} data={data} layoutMode="grid" />
);
Loading

0 comments on commit 0eb109c

Please sign in to comment.