Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
50e886e
Add column hover effect to table cells
Sep 25, 2025
f4e21e3
Refactor table hover effect and improve code readability
Sep 25, 2025
42132af
Implement column hover effect in table component and enhance styling
Sep 25, 2025
9146e7d
Refactor column hover effect implementation in Table component for im…
Sep 25, 2025
a1c5ecd
Increase column hover effect range in Table component to support up t…
Sep 25, 2025
a5f9d2a
Refactor commented-out row hover styles in Table component for clarity
Sep 25, 2025
469725c
Refactor column hover styles in Table component for improved clarity …
Sep 29, 2025
b9dcb5a
No hover on td for row
Sep 29, 2025
cd11fae
Remove unnecessary newline before column hover mixin inclusion in Tab…
Sep 29, 2025
170bfdc
Added -1 when hovering td to get the correct column to be highlited
Sep 29, 2025
6f1e455
Refactor Table component layout and styles for improved structure and…
Oct 8, 2025
2fc824e
Fix formatting in Table component styles and improve column hover mix…
Oct 8, 2025
b3f0cc8
Merge branch 'main' into feature/PXWEB2-202-freeze-and-hover
Oct 8, 2025
8757d39
Merge branch 'main' into feature/PXWeb2-202-hover
Oct 23, 2025
b367db3
Merge branch 'main' into feature/PXWeb2-202-hover
Oct 27, 2025
e007776
Enhance table interactivity with column hover effect and data attributes
Oct 28, 2025
7df6028
Refactor table hover effect and improve code readability
Oct 28, 2025
e7ea9ff
Highligth empty cells an
Oct 28, 2025
0425fbe
Refactor mouse event handling for table column hover effect to improv…
Oct 28, 2025
f64fa76
Add tests for table column hover behavior and highlight removal on st…
Oct 28, 2025
8cc73e0
Add tests for table column hover behavior and highlight removal on st…
Oct 28, 2025
1973915
Refactor table column hover tests for improved clarity and maintainab…
Oct 29, 2025
d2771ed
Refactor hover test for improved readability and maintainability
Oct 29, 2025
008f179
Refactor table event handling to improve readability and maintainability
Oct 29, 2025
1880363
Remove !important from hover background styles for improved specificity
Oct 29, 2025
0850066
Refactor column hover logic for improved performance and readability
Oct 29, 2025
e9ee5f6
Refactor column hover logic for improved readability
Oct 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions packages/pxweb2-ui/src/lib/components/Table/Table.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@

tbody tr {
&:hover {
background: var(--px-color-surface-subtle) !important;

th {
background: var(--px-color-surface-subtle) !important;
}
background: var(--px-color-surface-subtle);
}
}

Expand Down Expand Up @@ -124,6 +120,7 @@
}
th.stub-9 {
border-left: none;

@media screen and (min-width: fixed.$breakpoints-small-min-width) {
padding-left: 156px;
}
Expand All @@ -140,7 +137,6 @@
text-align: right;
border-top: 1px solid var(--px-color-border-default);
border-left: 1px solid var(--px-color-border-default);

@media screen and (min-width: fixed.$breakpoints-small-min-width) {
padding: 8px 12px;
}
Expand Down Expand Up @@ -254,3 +250,6 @@
border: none;
}
}
.table td.colHover {
background: var(--px-color-surface-subtle);
}
24 changes: 22 additions & 2 deletions packages/pxweb2-ui/src/lib/components/Table/Table.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { render } from '@testing-library/react';
import { render, fireEvent } from '@testing-library/react';
import { describe, it, expect } from 'vitest';

import Table from './Table';
import { pxTable } from './testData';

Expand Down Expand Up @@ -45,4 +44,25 @@ describe('Table', () => {
});
expect(found).toBe(false);
});

it('highlights column on header hover', () => {
const { container } = render(<Table pxtable={pxTable} isMobile={false} />);
console.log(container.innerHTML); // Debug: check for data-col and stub classes

// Find a leaf header cell
const leafHeader = container.querySelector(
'thead tr:last-child th[data-col]',
);
expect(leafHeader).toBeTruthy();

// Simulate mouseover
fireEvent.mouseOver(leafHeader!);

// Find highlighted data cells
const col = leafHeader!.getAttribute('data-col');
const highlightedCells = container.querySelectorAll(
`td[data-col="${col}"][class*="colHover"]`,
);
expect(highlightedCells.length).toBeGreaterThan(0);
});
});
80 changes: 76 additions & 4 deletions packages/pxweb2-ui/src/lib/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { memo, useMemo } from 'react';
import { memo, useMemo, useRef, useEffect } from 'react';
import cl from 'clsx';

import classes from './Table.module.scss';
Expand Down Expand Up @@ -115,8 +115,67 @@ export const Table = memo(function Table({
headingDataCellCodes[i] = dataCellCodes;
}

const tableRef = useRef<HTMLTableElement>(null);

useEffect(() => {
const table = tableRef.current;
if (!table) {
return;
}

let currentCol: string | null = null;

function clear() {
for (const cell of Array.from(
table!.querySelectorAll('.' + classes.colHover),
)) {
cell.classList.remove(classes.colHover);
}
currentCol = null;
}

function handleOver(e: MouseEvent) {
// Only highlight if hovering a data cell (td[data-col]) or a leaf header cell (th[data-col] in last header row)
const td = (e.target as HTMLElement).closest('td[data-col]');
const th = (e.target as HTMLElement).closest(
'thead tr:last-child th[data-col]',
);
// If hovering stub or emptyTableData, clear highlight
if (
(e.target as HTMLElement).closest('.stub') ||
(e.target as HTMLElement).closest('.emptyTableData') ||
(!td && !th)
) {
clear();
return;
}
// Determine column
const cell = td || th;
const col = (cell as HTMLElement).dataset.col;
if (!col || col === currentCol) {
return;
}
clear();
// Highlight only data cells in the same column
for (const cell of Array.from(
table!.querySelectorAll(`td[data-col="${col}"]`),
)) {
cell.classList.add(classes.colHover);
}
currentCol = col;
}

table.addEventListener('mouseover', handleOver);
table.addEventListener('mouseleave', clear);
return () => {
table.removeEventListener('mouseover', handleOver);
table.removeEventListener('mouseleave', clear);
};
}, []);

return (
<table
ref={tableRef}
className={cl(classes.table, classes[`bodyshort-medium`]) + cssClasses}
aria-label={pxtable.metadata.label}
>
Expand Down Expand Up @@ -224,6 +283,12 @@ export function createHeading(
idxRepetitionCurrentHeadingLevel === 1 &&
table.stub.length === 0,
})}
// Only add data-col for leaf header row
data-col={
idxHeadingLevel === table.heading.length - 1
? String(columnIndex + tableMeta.columnOffset)
: undefined
}
>
{variable.values[i].label}
</th>,
Expand Down Expand Up @@ -608,7 +673,11 @@ function fillEmpty(

// Loop through all data columns in the table
for (let i = 0; i < maxCols; i++) {
tableRow.push(<td key={getNewKey()}>{emptyText}</td>);
tableRow.push(
<td key={getNewKey()} data-col={String(i + tableMeta.columnOffset)}>
{emptyText}
</td>,
);
}
}

Expand All @@ -632,7 +701,6 @@ function fillData(
const maxCols = tableMeta.columns - tableMeta.columnOffset;

// Loop through all data columns in the table

for (let i = 0; i < maxCols; i++) {
// Merge the metadata structure for the dimensions of the stub and header cells
const dataCellCodes = stubDataCellCodes.concat(headingDataCellCodes[i]);
Expand All @@ -654,7 +722,11 @@ function fillData(
const dataValue = getPxTableData(table.data.cube, dimensions);

tableRow.push(
<td key={getNewKey()} headers={headers}>
<td
key={getNewKey()}
headers={headers}
data-col={String(i + tableMeta.columnOffset)}
>
{dataValue?.formattedValue}
</td>,
);
Expand Down