@@ -16,6 +16,8 @@ interface ThresholdSliderProps {
1616 onEnabledChange : ( enabled : boolean ) => void ;
1717 /** Orientation of the slider */
1818 orientation : "horizontal" | "vertical" ;
19+ /** Height of the bar for vertical positioning (horizontal orientation only) */
20+ barHeight ?: number ;
1921}
2022
2123// Threshold at which we consider auto-compaction disabled (dragged all the way right/down)
@@ -27,6 +29,7 @@ export const ThresholdSlider: React.FC<ThresholdSliderProps> = ({
2729 onThresholdChange,
2830 onEnabledChange,
2931 orientation,
32+ barHeight = 6 ,
3033} ) => {
3134 const containerRef = useRef < HTMLDivElement > ( null ) ;
3235 const [ isDragging , setIsDragging ] = useState ( false ) ;
@@ -107,59 +110,130 @@ export const ThresholdSlider: React.FC<ThresholdSliderProps> = ({
107110 : "Auto-compact disabled · Drag left to enable" ;
108111
109112 if ( orientation === "horizontal" ) {
113+ // Render as a positioned overlay - the parent should have position:relative
110114 return (
111- < div
112- ref = { containerRef }
113- className = "absolute inset-0 cursor-ew-resize"
114- onMouseDown = { handleMouseDown }
115- >
116- < TooltipWrapper inline >
117- { /* Vertical line indicator - extends above and below the bar */ }
115+ < TooltipWrapper inline >
116+ < div
117+ ref = { containerRef }
118+ className = "absolute cursor-ew-resize"
119+ style = { {
120+ left : 0 ,
121+ right : 0 ,
122+ top : "50%" ,
123+ transform : "translateY(-50%)" ,
124+ height : barHeight + 16 , // bar + 8px padding each side for easier grabbing
125+ } }
126+ onMouseDown = { handleMouseDown }
127+ >
128+ { /* Vertical line indicator with grab handle */ }
118129 < div
119- className = { `pointer-events-none absolute transition-opacity ${
120- isDragging ? "opacity-100" : "opacity-60 hover:opacity-100"
121- } ${ enabled ? "bg-plan-mode" : "bg-muted" } `}
130+ className = "pointer-events-none absolute flex flex-col items-center"
122131 style = { {
123132 left : `${ position } %` ,
124133 transform : "translateX(-50%)" ,
125- width : "2px" ,
126- top : "-4px" ,
127- bottom : "-4px" ,
134+ top : 0 ,
135+ bottom : 0 ,
128136 } }
129- />
130- < Tooltip align = "center" width = "auto" >
131- { tooltipContent }
132- </ Tooltip >
133- </ TooltipWrapper >
134- </ div >
137+ >
138+ { /* Top handle - small triangle */ }
139+ < div
140+ className = { `h-0 w-0 shrink-0 transition-opacity ${
141+ isDragging ? "opacity-100" : "opacity-70"
142+ } `}
143+ style = { {
144+ borderLeft : "4px solid transparent" ,
145+ borderRight : "4px solid transparent" ,
146+ borderTop : `5px solid ${ enabled ? "var(--color-plan-mode)" : "var(--color-muted)" } ` ,
147+ } }
148+ />
149+ { /* The line itself */ }
150+ < div
151+ className = { `flex-1 transition-opacity ${ isDragging ? "opacity-100" : "opacity-70" } ` }
152+ style = { {
153+ width : 2 ,
154+ background : enabled ? "var(--color-plan-mode)" : "var(--color-muted)" ,
155+ } }
156+ />
157+ { /* Bottom handle - small triangle pointing up */ }
158+ < div
159+ className = { `h-0 w-0 shrink-0 transition-opacity ${
160+ isDragging ? "opacity-100" : "opacity-70"
161+ } `}
162+ style = { {
163+ borderLeft : "4px solid transparent" ,
164+ borderRight : "4px solid transparent" ,
165+ borderBottom : `5px solid ${ enabled ? "var(--color-plan-mode)" : "var(--color-muted)" } ` ,
166+ } }
167+ />
168+ </ div >
169+ </ div >
170+ < Tooltip align = "center" width = "auto" >
171+ { tooltipContent }
172+ </ Tooltip >
173+ </ TooltipWrapper >
135174 ) ;
136175 }
137176
138177 // Vertical orientation
139178 return (
140- < div
141- ref = { containerRef }
142- className = "absolute inset-0 cursor-ns-resize"
143- onMouseDown = { handleMouseDown }
144- >
145- < TooltipWrapper inline >
146- { /* Horizontal line indicator - extends left and right of the bar */ }
179+ < TooltipWrapper inline >
180+ < div
181+ ref = { containerRef }
182+ className = "absolute cursor-ns-resize"
183+ style = { {
184+ top : 0 ,
185+ bottom : 0 ,
186+ left : "50%" ,
187+ transform : "translateX(-50%)" ,
188+ width : 20 , // wider hit area
189+ } }
190+ onMouseDown = { handleMouseDown }
191+ >
192+ { /* Horizontal line indicator with grab handles */ }
147193 < div
148- className = { `pointer-events-none absolute transition-opacity ${
149- isDragging ? "opacity-100" : "opacity-60 hover:opacity-100"
150- } ${ enabled ? "bg-plan-mode" : "bg-muted" } `}
194+ className = "pointer-events-none absolute flex items-center"
151195 style = { {
152196 top : `${ position } %` ,
153197 transform : "translateY(-50%)" ,
154- height : "2px" ,
155- left : "-2px" ,
156- right : "-2px" ,
198+ left : 0 ,
199+ right : 0 ,
157200 } }
158- />
159- < Tooltip align = "center" width = "auto" >
160- { tooltipContent }
161- </ Tooltip >
162- </ TooltipWrapper >
163- </ div >
201+ >
202+ { /* Left handle - small triangle */ }
203+ < div
204+ className = { `h-0 w-0 shrink-0 transition-opacity ${
205+ isDragging ? "opacity-100" : "opacity-70"
206+ } `}
207+ style = { {
208+ borderTop : "4px solid transparent" ,
209+ borderBottom : "4px solid transparent" ,
210+ borderLeft : `5px solid ${ enabled ? "var(--color-plan-mode)" : "var(--color-muted)" } ` ,
211+ } }
212+ />
213+ { /* The line itself */ }
214+ < div
215+ className = { `flex-1 transition-opacity ${ isDragging ? "opacity-100" : "opacity-70" } ` }
216+ style = { {
217+ height : 2 ,
218+ background : enabled ? "var(--color-plan-mode)" : "var(--color-muted)" ,
219+ } }
220+ />
221+ { /* Right handle - small triangle pointing left */ }
222+ < div
223+ className = { `h-0 w-0 shrink-0 transition-opacity ${
224+ isDragging ? "opacity-100" : "opacity-70"
225+ } `}
226+ style = { {
227+ borderTop : "4px solid transparent" ,
228+ borderBottom : "4px solid transparent" ,
229+ borderRight : `5px solid ${ enabled ? "var(--color-plan-mode)" : "var(--color-muted)" } ` ,
230+ } }
231+ />
232+ </ div >
233+ </ div >
234+ < Tooltip align = "center" width = "auto" >
235+ { tooltipContent }
236+ </ Tooltip >
237+ </ TooltipWrapper >
164238 ) ;
165239} ;
0 commit comments