Skip to content

Commit

Permalink
⏪ - fix: revert attempt to improve stickyfix behaviour (fac49fb) due …
Browse files Browse the repository at this point in the history
…to bug where thead would overlap data row
  • Loading branch information
svenvandescheur committed Dec 9, 2024
1 parent 451a237 commit 2f8fff1
Showing 1 changed file with 24 additions and 31 deletions.
55 changes: 24 additions & 31 deletions src/components/data/datagrid/datagridthead.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ export const DataGridTHead = <
>() => {
const ref = useRef<HTMLTableSectionElement>(null);

const thead = ref.current;
const table = thead?.parentNode as HTMLTableElement | undefined;
const scrollPane = table?.parentNode as HTMLDivElement | undefined;
const toolbar = scrollPane?.previousSibling as HTMLDivElement | undefined;

const {
allowOverflowX,
dataGridId,
Expand All @@ -40,49 +35,53 @@ export const DataGridTHead = <
window.removeEventListener("resize", stickyFix);
window.removeEventListener("scroll", stickyFix);
};
}, [ref.current, height, renderableFields]);
}, [ref.current, height]);

/**
* Fixes sticky behaviour due to `overflow-y: auto;` and `overflow-x: auto;`
* combination not being compatible with native sticky in all cases.
*/
const stickyFix = () => {
if (!ref.current || !thead || !table || !scrollPane || !toolbar) {
if (!ref.current) {
return;
}

requestAnimationFrame(() => {
thead.style.top = "";
const thead = ref.current;
const table = thead.parentNode as HTMLTableElement;
const scrollPane = table?.parentNode as HTMLDivElement;
const toolbar = scrollPane.previousSibling as HTMLDivElement | null;

requestAnimationFrame(() => {
const classOverflowX = "mykn-datagrid__scrollpane--overflow-x";
const classOverflowY = "mykn-datagrid__scrollpane--overflow-y";

// Reset.
thead.style.top = "";
scrollPane.classList.remove(classOverflowX);
scrollPane.classList.remove(classOverflowY);

// Active conditions.
const isHeightSet = Boolean(height);
const isHeight100Percent = height === "100%"; // (100)% is edge case.
const isHeightExplicitlySet = isHeightSet && !isHeight100Percent;
const isScrollX =
allowOverflowX && scrollPane.scrollWidth - scrollPane.clientWidth > 20;
allowOverflowX && scrollPane.scrollWidth > scrollPane.clientWidth;

// Available fixes.
const shouldOverflowX = isScrollX && !isHeightExplicitlySet;
const shouldOverflowY = isHeightExplicitlySet;
const shouldStickyFix = shouldOverflowX;
const shouldOverflowX = !isHeightSet && isScrollX;
const shouldOverflowY = isHeightSet;
const shouldStickyFix = isHeight100Percent || (!height && isScrollX);

// Apply overflow CSS rules using classes.
if (scrollPane.classList.contains(classOverflowX) !== shouldOverflowX) {
scrollPane.classList.toggle(classOverflowX, shouldOverflowX);
}
if (scrollPane.classList.contains(classOverflowY) !== shouldOverflowY) {
scrollPane.classList.toggle(classOverflowY, shouldOverflowY);
}
scrollPane.classList.toggle(classOverflowX, shouldOverflowX);
scrollPane.classList.toggle(classOverflowY, shouldOverflowY);

// No need for fallback implementation as only `overflow-y: auto;` has to
// be set.
if (!shouldStickyFix) return;
if (!shouldStickyFix) {
return;
}

// Fix the sticky top behaviour.
thead.style.transform = "";
const boundingClientRect = thead.getBoundingClientRect();
const boundingTop = boundingClientRect.top;

Expand All @@ -93,16 +92,10 @@ export const DataGridTHead = <
// Invert the negative offset caused by scrolling and push the position
// in the opposite direction, then apply some compensation for the
// existing offset.
const compensation = Math.max(
const compensation =
boundingTop * -1 +
(toolbar ? toolbar.clientHeight : 0) * (isHeight100Percent ? 1 : 2),
0,
);

// No compensation.
if (!compensation) return;

thead.style.top = `${compensation}px`;
(toolbar ? toolbar.clientHeight : 0) * (isHeight100Percent ? 1 : 2);
thead.style.top = compensation + "px";
});
};

Expand Down

0 comments on commit 2f8fff1

Please sign in to comment.