1- import { batch , createEffect , createMemo , createSignal , For , type JSX } from 'solid-js' ;
1+ import { batch , createEffect , createMemo , createSignal , For , onCleanup , type JSX } from 'solid-js' ;
22import { getPanelUserSize , setPanelUserSize , deletePanelUserSize } from '../store/store' ;
33
44export interface PanelChild {
@@ -20,10 +20,10 @@ export interface PanelChild {
2020 * smaller than their pinned size would be (e.g., a toolbar that collapses
2121 * when its body is empty), so a stale pin can't leave a visible gap. */
2222 noPin ?: ( ) => boolean ;
23- /** Flex -grow weight for absorbers. Defaults to 1 (equal share). Use a
24- * smaller value to give an absorber less space than others, e.g. 0.5
25- * for notes-files so the AI terminal gets roughly 2/3 of remaining space . */
26- flexGrow ?: number ;
23+ /** Relative flex -grow weight among absorbers. Defaults to 1 (equal share).
24+ * Ignored on non-absorbers. Use a smaller value to give an absorber less
25+ * space than its siblings, e.g. 0.5 so the AI terminal gets ~ 2/3. */
26+ absorberWeight ?: number ;
2727}
2828
2929interface ResizablePanelProps {
@@ -43,7 +43,7 @@ interface ResizablePanelProps {
4343
4444export function ResizablePanel ( props : ResizablePanelProps ) {
4545 const [ draggingIdx , setDraggingIdx ] = createSignal < number | null > ( null ) ;
46- const [ dragOverride , setDragOverride ] = createSignal < Record < number , number > > ( { } ) ;
46+ const [ dragOverride , setDragOverride ] = createSignal < Record < string , number > > ( { } ) ;
4747 /** Stable per-ID refs so drag measurement survives dynamic children changes. */
4848 const wrapperRefs = new Map < string , HTMLDivElement > ( ) ;
4949
@@ -99,14 +99,15 @@ export function ResizablePanel(props: ResizablePanelProps) {
9999 if ( stale . length > 0 ) deletePanelUserSize ( stale ) ;
100100 } ) ;
101101
102- function childStyle ( child : PanelChild , idx : number ) : JSX . CSSProperties {
102+ function childStyle ( child : PanelChild ) : JSX . CSSProperties {
103103 const noPin = child . noPin ?.( ) === true ;
104104 // noPin children can't be sized by drag override or persisted pin — they
105105 // stay content-sized so an empty inner state can't leave a visible gap.
106106 const key = keyFor ( child . id ) ;
107- const pinned = noPin
107+ const raw = noPin
108108 ? undefined
109- : ( dragOverride ( ) [ idx ] ?? ( key ? getPanelUserSize ( key ) : undefined ) ) ;
109+ : ( dragOverride ( ) [ child . id ] ?? ( key ? getPanelUserSize ( key ) : undefined ) ) ;
110+ const pinned = raw !== undefined && Number . isFinite ( raw ) && raw > 0 ? raw : undefined ;
110111 const dim = isHorizontal ( ) ? 'width' : 'height' ;
111112 const minDim = isHorizontal ( ) ? 'min-width' : 'min-height' ;
112113 const maxDim = isHorizontal ( ) ? 'max-width' : 'max-height' ;
@@ -117,7 +118,7 @@ export function ResizablePanel(props: ResizablePanelProps) {
117118 // Persisted pins on absorbers use flex-grow ratio so they scale when the
118119 // container resizes (e.g. notes/changed-files in a horizontal split that
119120 // should stay proportional with the window).
120- if ( isAbsorber ( child . id ) && dragOverride ( ) [ idx ] === undefined ) {
121+ if ( isAbsorber ( child . id ) && dragOverride ( ) [ child . id ] === undefined ) {
121122 return {
122123 flex : `${ pinned } 1 0` ,
123124 [ minDim ] : `${ min } px` ,
@@ -132,7 +133,7 @@ export function ResizablePanel(props: ResizablePanelProps) {
132133 } ;
133134 }
134135 if ( isAbsorber ( child . id ) ) {
135- const fg = child . flexGrow ?? 1 ;
136+ const fg = child . absorberWeight ?? 1 ;
136137 return {
137138 flex : `${ fg } 1 0` ,
138139 [ minDim ] : `${ min } px` ,
@@ -222,12 +223,12 @@ export function ResizablePanel(props: ResizablePanelProps) {
222223 // Skip the override on noPin children so they stay content-sized; also
223224 // skip on a sole absorber adjacent to a noPin sibling, since pinning the
224225 // absorber temporarily would steal the space the noPin child can't take.
225- const override : Record < number , number > = { } ;
226+ const override : Record < string , number > = { } ;
226227 if ( ! leftNoPin && ! ( leftIsAbs && rightNoPin && soleAbs ) ) {
227- override [ handleIdx ] = latestLeft ;
228+ override [ leftChild . id ] = latestLeft ;
228229 }
229230 if ( ! rightNoPin && ! ( rightIsAbs && leftNoPin && soleAbs ) ) {
230- override [ handleIdx + 1 ] = latestRight ;
231+ override [ rightChild . id ] = latestRight ;
231232 }
232233 setDragOverride ( override ) ;
233234 } ;
@@ -300,8 +301,9 @@ export function ResizablePanel(props: ResizablePanelProps) {
300301 class = "rp-cell"
301302 ref = { ( el ) => {
302303 wrapperRefs . set ( child . id , el ) ;
304+ onCleanup ( ( ) => wrapperRefs . delete ( child . id ) ) ;
303305 } }
304- style = { childStyle ( child , i ( ) ) }
306+ style = { childStyle ( child ) }
305307 >
306308 { child . content ( ) }
307309 </ div >
0 commit comments