add table row hover effect

This commit is contained in:
jeffvli
2025-10-04 03:39:07 -07:00
parent 9d1b2a7c72
commit 3ce6a6fe95
3 changed files with 95 additions and 1 deletions
@@ -1,4 +1,5 @@
.container {
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
@@ -20,6 +21,8 @@
}
.content {
position: relative;
z-index: 2;
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
@@ -37,6 +40,25 @@
border-bottom: 1px solid var(--theme-colors-border);
}
.container.data-row.row-hover-enabled:hover::before,
.container.data-row.row-hover-enabled.row-hovered::before {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
pointer-events: none;
content: '';
background-color: var(--theme-colors-surface);
opacity: 0.7;
}
.container.data-row > * {
position: relative;
z-index: 2;
}
.header-container {
background: none;
}
@@ -1,5 +1,5 @@
import clsx from 'clsx';
import React, { ReactNode } from 'react';
import React, { ReactNode, useEffect, useRef } from 'react';
import { CellComponentProps } from 'react-window-v2';
import styles from './item-table-list-column.module.css';
@@ -114,17 +114,51 @@ export const TableColumnTextContainer = (
type: TableColumn;
},
) => {
const containerRef = useRef<HTMLDivElement>(null);
const isDataRow = props.enableHeader && props.rowIndex > 0;
useEffect(() => {
if (!isDataRow || !containerRef.current || !props.enableRowHover) return;
const container = containerRef.current;
const rowIndex = props.rowIndex;
const handleMouseEnter = () => {
// Find all cells in the same row and add hover class
const allCells = document.querySelectorAll(`[data-row-index="${rowIndex}"]`);
allCells.forEach((cell) => cell.classList.add(styles.rowHovered));
};
const handleMouseLeave = () => {
// Remove hover class from all cells in the same row
const allCells = document.querySelectorAll(`[data-row-index="${rowIndex}"]`);
allCells.forEach((cell) => cell.classList.remove(styles.rowHovered));
};
container.addEventListener('mouseenter', handleMouseEnter);
container.addEventListener('mouseleave', handleMouseLeave);
return () => {
container.removeEventListener('mouseenter', handleMouseEnter);
container.removeEventListener('mouseleave', handleMouseLeave);
};
}, [isDataRow, props.rowIndex, props.enableRowHover]);
return (
<div
className={clsx(styles.container, props.containerClassName, {
[styles.center]: props.columns[props.columnIndex].align === 'center',
[styles.compact]: props.size === 'compact',
[styles.dataRow]: isDataRow,
[styles.left]: props.columns[props.columnIndex].align === 'start',
[styles.right]: props.columns[props.columnIndex].align === 'end',
[styles.rowHoverEnabled]: isDataRow && props.enableRowHover,
[styles.withRowBorder]:
props.enableRowBorders && props.enableHeader && props.rowIndex > 0,
})}
data-row-index={isDataRow ? props.rowIndex : undefined}
onClick={(e) => props.handleExpand(e, props.data[props.rowIndex], props.itemType)}
ref={containerRef}
style={props.style}
>
<Text
@@ -146,17 +180,51 @@ export const TableColumnContainer = (
type: TableColumn;
},
) => {
const containerRef = useRef<HTMLDivElement>(null);
const isDataRow = props.enableHeader && props.rowIndex > 0;
useEffect(() => {
if (!isDataRow || !containerRef.current || !props.enableRowHover) return;
const container = containerRef.current;
const rowIndex = props.rowIndex;
const handleMouseEnter = () => {
// Find all cells in the same row and add hover class
const allCells = document.querySelectorAll(`[data-row-index="${rowIndex}"]`);
allCells.forEach((cell) => cell.classList.add(styles.rowHovered));
};
const handleMouseLeave = () => {
// Remove hover class from all cells in the same row
const allCells = document.querySelectorAll(`[data-row-index="${rowIndex}"]`);
allCells.forEach((cell) => cell.classList.remove(styles.rowHovered));
};
container.addEventListener('mouseenter', handleMouseEnter);
container.addEventListener('mouseleave', handleMouseLeave);
return () => {
container.removeEventListener('mouseenter', handleMouseEnter);
container.removeEventListener('mouseleave', handleMouseLeave);
};
}, [isDataRow, props.rowIndex, props.enableRowHover]);
return (
<div
className={clsx(styles.container, props.containerClassName, {
[styles.center]: props.columns[props.columnIndex].align === 'center',
[styles.compact]: props.size === 'compact',
[styles.dataRow]: isDataRow,
[styles.left]: props.columns[props.columnIndex].align === 'start',
[styles.right]: props.columns[props.columnIndex].align === 'end',
[styles.rowHoverEnabled]: isDataRow && props.enableRowHover,
[styles.withRowBorder]:
props.enableRowBorders && props.enableHeader && props.rowIndex > 0,
})}
data-row-index={isDataRow ? props.rowIndex : undefined}
onClick={(e) => props.handleExpand(e, props.data[props.rowIndex], props.itemType)}
ref={containerRef}
style={props.style}
>
{props.children}
@@ -30,6 +30,7 @@ export interface CellProps {
data: unknown[];
enableHeader?: boolean;
enableRowBorders?: boolean;
enableRowHover?: boolean;
handleExpand: (e: MouseEvent<HTMLDivElement>, item: unknown, itemType: LibraryItem) => void;
itemType: LibraryItem;
size?: 'compact' | 'default';
@@ -49,6 +50,7 @@ interface ItemTableListProps {
enableExpansion?: boolean;
enableHeader?: boolean;
enableRowBorders?: boolean;
enableRowHover?: boolean;
enableSelection?: boolean;
headerHeight?: number;
initialTopMostItemIndex?:
@@ -95,6 +97,7 @@ export const ItemTableList = ({
data,
enableHeader = true,
enableRowBorders = false,
enableRowHover = false,
headerHeight = 40,
initialTopMostItemIndex,
itemType,
@@ -548,6 +551,7 @@ export const ItemTableList = ({
data,
enableHeader,
enableRowBorders,
enableRowHover,
handleExpand,
itemType,
size,