From b47d8db9bc0c6abe14c635ed43bdaad551254de5 Mon Sep 17 00:00:00 2001 From: Luke Parker <10430890+Hona@users.noreply.github.com> Date: Fri, 2 Oct 2026 12:59:37 +1000 Subject: [PATCH] fix(app): keep stuck timeline headers out of the title fade (#52639) --- .../e2e/regression/patch-sticky-header.spec.ts | 9 ++++++--- .../app/src/session/session-identity-header.tsx | 17 +++++++++++------ .../session-ui/src/tools/tool-group.stories.tsx | 9 ++++++--- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/packages/app/e2e/regression/patch-sticky-header.spec.ts b/packages/app/e2e/regression/patch-sticky-header.spec.ts index 53e8cecbe90..fa1979b9d51 100644 --- a/packages/app/e2e/regression/patch-sticky-header.spec.ts +++ b/packages/app/e2e/regression/patch-sticky-header.spec.ts @@ -220,13 +220,16 @@ for (const scenario of scenarios) { const top = sessionTop + (group?.getBoundingClientRect().height ?? 0) const rect = element.getBoundingClientRect() const trigger = element.querySelector("button")! + // The header stuck directly below the session title sits where the title's fade starts. + const hits = (target: Element, box: DOMRect) => + [box.top + 1, box.top + box.height / 2].every((y) => + target.contains(document.elementFromPoint(box.left + box.width / 2, y)), + ) return { gap: Math.abs(rect.top - top - (toolTitle?.getBoundingClientRect().height ?? 0)), groupGap: group ? Math.abs(group.getBoundingClientRect().top - sessionTop) : 0, titleGap: toolTitle ? Math.abs(toolTitle.getBoundingClientRect().top - top) : 0, - clickable: trigger.contains( - document.elementFromPoint(rect.left + rect.width / 2, rect.top + rect.height / 2), - ), + clickable: hits(trigger, rect) && (!group || hits(group, group.getBoundingClientRect())), } }), ) diff --git a/packages/app/src/session/session-identity-header.tsx b/packages/app/src/session/session-identity-header.tsx index 205fbd42ba0..cf40c6345f6 100644 --- a/packages/app/src/session/session-identity-header.tsx +++ b/packages/app/src/session/session-identity-header.tsx @@ -30,12 +30,17 @@ import "./session-identity-header.css" export function SessionTitleHeader(props: ParentProps) { return ( -
- {props.children} -
+ <> + {/* The bottom inset reserves room for the fade without covering rows stuck below the bar. */} +
+
{props.children}
+
+ {/* Stuck timeline headers stack above this fade, so it only fades content scrolling under the bar. */} +