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. */} +