Skip to content

Commit 33d5d61

Browse files
backnotpropclaude
andauthored
fix: prevent resize handle from covering scrollbar (#359)
* fix: prevent resize handle touch area from covering scrollbar (#354) The ResizeHandle touch target extended 8px in both directions (-inset-x-2), overlapping the 6px scrollbar on the adjacent content area. Users could see the scrollbar but couldn't grab it because the resize handle intercepted clicks. Add a `side` prop so the touch area only extends outward (away from the scroll container) — left handles extend left, right handles extend right. Closes #354 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: remove transform/opacity from global transition to fix choppy scroll The global `*` rule applied 150ms transitions on transform and opacity to every DOM element. During scroll, the compositor fights these transitions on sticky headers, annotation highlights, and layer compositing — causing visible choppiness. Narrowed to color, background-color, border-color, box-shadow only. These handle theme switching and hover states without affecting scroll performance. Components needing transform/opacity transitions already declare their own via Tailwind classes (205 usages across 45 files). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7ed85df commit 33d5d61

4 files changed

Lines changed: 17 additions & 8 deletions

File tree

packages/editor/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ const App: React.FC = () => {
12361236
onFetchVersions={planDiff.fetchVersions}
12371237
onFetchProjectPlans={planDiff.fetchProjectPlans}
12381238
/>
1239-
<ResizeHandle {...tocResize.handleProps} className="hidden lg:block" />
1239+
<ResizeHandle {...tocResize.handleProps} className="hidden lg:block" side="left" />
12401240
</>
12411241
)}
12421242

@@ -1323,7 +1323,7 @@ const App: React.FC = () => {
13231323
</main>
13241324

13251325
{/* Resize Handle */}
1326-
{isPanelOpen && <ResizeHandle {...panelResize.handleProps} className="hidden md:block" />}
1326+
{isPanelOpen && <ResizeHandle {...panelResize.handleProps} className="hidden md:block" side="right" />}
13271327

13281328
{/* Annotation Panel */}
13291329
<AnnotationPanel

packages/review-editor/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ const ReviewApp: React.FC = () => {
878878
onSelectSearchMatch={handleSelectSearchMatch}
879879
onStepSearchMatch={stepSearchMatch}
880880
/>
881-
<ResizeHandle {...fileTreeResize.handleProps} />
881+
<ResizeHandle {...fileTreeResize.handleProps} side="left" />
882882
</>
883883
)}
884884

@@ -970,7 +970,7 @@ const ReviewApp: React.FC = () => {
970970
</main>
971971

972972
{/* Resize Handle */}
973-
{isPanelOpen && <ResizeHandle {...panelResize.handleProps} />}
973+
{isPanelOpen && <ResizeHandle {...panelResize.handleProps} side="right" />}
974974

975975
{/* Annotations panel */}
976976
<ReviewPanel

packages/ui/components/ResizeHandle.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import type { ResizeHandleProps as BaseProps } from '../hooks/useResizablePanel'
33

44
interface Props extends BaseProps {
55
className?: string;
6+
/** Which side of the content the handle is on — extends touch area away from content */
7+
side?: 'left' | 'right';
68
}
79

810
export const ResizeHandle: React.FC<Props> = ({
@@ -11,6 +13,7 @@ export const ResizeHandle: React.FC<Props> = ({
1113
onTouchStart,
1214
onDoubleClick,
1315
className,
16+
side,
1417
}) => (
1518
<div
1619
className={`relative w-1 cursor-col-resize flex-shrink-0 group${className ? ` ${className}` : ''}`}
@@ -19,9 +22,13 @@ export const ResizeHandle: React.FC<Props> = ({
1922
<div className={`absolute inset-y-0 inset-x-0 transition-colors ${
2023
isDragging ? 'bg-primary/50' : 'group-hover:bg-border'
2124
}`} />
22-
{/* Wider touch area */}
25+
{/* Wider touch area — extends outward from content to avoid covering scrollbar */}
2326
<div
24-
className="absolute inset-y-0 -inset-x-2"
27+
className={`absolute inset-y-0 ${
28+
side === 'left' ? 'right-0 -left-2' :
29+
side === 'right' ? 'left-0 -right-2' :
30+
'-inset-x-2'
31+
}`}
2532
onMouseDown={onMouseDown}
2633
onTouchStart={onTouchStart}
2734
onDoubleClick={onDoubleClick}

packages/ui/theme.css

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,11 @@ body {
101101
background: oklch(from var(--primary) l c h / 0.3);
102102
}
103103

104-
/* Smooth transitions */
104+
/* Smooth transitions for theme switching and hover states.
105+
Only color properties — transform/opacity are handled per-component
106+
to avoid interfering with scroll compositing. */
105107
* {
106-
transition-property: color, background-color, border-color, box-shadow, opacity, transform;
108+
transition-property: color, background-color, border-color, box-shadow;
107109
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
108110
transition-duration: 150ms;
109111
}

0 commit comments

Comments
 (0)