@@ -250,7 +250,7 @@ export type PanelId = 'files' | 'search' | 'changes' | 'editor' | 'agent' | 'ter
250250type PanelParams = {
251251 panelKey : string ;
252252 panelId : PanelId ;
253- content : React . ReactNode ;
253+ content ? : React . ReactNode ;
254254} ;
255255
256256type PanelPlacementDirection = 'above' | 'right' | 'below' | 'within' ;
@@ -288,6 +288,7 @@ type ScrollSnapshot = {
288288
289289type LayoutViewStateRegistry = {
290290 registerPanelViewState : ( panelKey : string , handlers : PanelViewStateHandlers ) => ( ) => void ;
291+ savePanelViewState : ( panelKey : string , state : unknown ) => void ;
291292} ;
292293
293294type LayoutProps = {
@@ -309,6 +310,7 @@ export type LayoutActions = {
309310} ;
310311
311312const LayoutViewStateContext = React . createContext < LayoutViewStateRegistry | null > ( null ) ;
313+ const LayoutRenderContext = React . createContext < ( ( panelId : PanelId , panelKey : string ) => React . ReactNode ) | null > ( null ) ;
312314
313315export const useLayoutPanelViewState = (
314316 panelKey : string ,
@@ -587,10 +589,15 @@ const getSplitPanelSizes = (
587589
588590const LayoutPanel : React . FC < IDockviewPanelProps < PanelParams > > = ( { params } ) => {
589591 const rootRef = useRef < HTMLDivElement | null > ( null ) ;
592+ const renderPanel = useContext ( LayoutRenderContext ) ;
593+ const registry = useContext ( LayoutViewStateContext ) ;
590594
591- const captureViewState = useCallback ( ( ) : ScrollSnapshot [ ] => {
595+ const captureViewState = useCallback ( ( ) : ScrollSnapshot [ ] | null => {
592596 const root = rootRef . current ;
593- return root ? getPanelScrollSnapshots ( root ) : [ ] ;
597+ if ( ! root || ! document . body . contains ( root ) || ( root . offsetWidth === 0 && root . offsetHeight === 0 ) ) {
598+ return null ;
599+ }
600+ return getPanelScrollSnapshots ( root ) ;
594601 } , [ ] ) ;
595602
596603 const restoreViewState = useCallback ( ( state : unknown ) => {
@@ -607,9 +614,24 @@ const LayoutPanel: React.FC<IDockviewPanelProps<PanelParams>> = ({ params }) =>
607614 restoreViewState,
608615 } ) ;
609616
617+ useEffect ( ( ) => {
618+ const element = rootRef . current ;
619+ if ( ! element || ! registry ) return ;
620+
621+ const handleScroll = ( ) => {
622+ const snapshot = getPanelScrollSnapshots ( element ) ;
623+ registry . savePanelViewState ( params . panelKey , snapshot ) ;
624+ } ;
625+
626+ element . addEventListener ( 'scroll' , handleScroll , { capture : true , passive : true } ) ;
627+ return ( ) => element . removeEventListener ( 'scroll' , handleScroll , { capture : true } ) ;
628+ } , [ params . panelKey , registry ] ) ;
629+
630+ const content = renderPanel ? renderPanel ( params . panelId , params . panelKey ) : params . content ;
631+
610632 return (
611633 < div ref = { rootRef } className = { `layout-dock-panel layout-dock-panel--${ params . panelId } ` } >
612- { params . content }
634+ { content }
613635 </ div >
614636 ) ;
615637} ;
@@ -660,6 +682,11 @@ const PanelPicker: React.FC<IDockviewPanelProps<PanelPickerParams>> = ({ params
660682 </ div >
661683) ;
662684
685+ const DOCKVIEW_COMPONENTS = {
686+ layoutPanel : LayoutPanel ,
687+ panelPicker : PanelPicker ,
688+ } ;
689+
663690const LayoutHeaderActions : React . FC < IDockviewHeaderActionsProps & {
664691 onSplitRight : ( api : DockviewApi , referencePanelId : string ) => void ;
665692 onSplitDown : ( api : DockviewApi , referencePanelId : string ) => void ;
@@ -791,12 +818,11 @@ const addPanel = (
791818 api : DockviewApi ,
792819 panelKey : string ,
793820 panelId : PanelId ,
794- content : React . ReactNode ,
821+ content ? : React . ReactNode ,
795822) : IDockviewPanel => {
796823 const definition = panelDefinitionById [ panelId ] ;
797824 const existing = api . getPanel ( panelKey ) ;
798825 if ( existing ) {
799- existing . api . updateParameters ( { panelId, panelKey, content } ) ;
800826 return existing ;
801827 }
802828
@@ -1015,15 +1041,23 @@ export const Layout: React.FC<LayoutProps> = ({
10151041 } ;
10161042 } , [ ] ) ;
10171043
1044+ const savePanelViewState = useCallback ( ( panelKey : string , state : unknown ) => {
1045+ panelViewStatesRef . current [ panelKey ] = state ;
1046+ } , [ ] ) ;
1047+
10181048 const viewStateRegistry = useMemo < LayoutViewStateRegistry > ( ( ) => ( {
10191049 registerPanelViewState,
1020- } ) , [ registerPanelViewState ] ) ;
1050+ savePanelViewState,
1051+ } ) , [ registerPanelViewState , savePanelViewState ] ) ;
10211052
10221053 const capturePanelViewStates = useCallback ( ( ) => {
10231054 const nextStates : Record < string , unknown > = { } ;
10241055
10251056 panelViewStateHandlersRef . current . forEach ( ( handlers , panelKey ) => {
1026- nextStates [ panelKey ] = handlers . captureViewState ( ) ;
1057+ const state = handlers . captureViewState ( ) ;
1058+ if ( state !== null && state !== undefined ) {
1059+ nextStates [ panelKey ] = state ;
1060+ }
10271061 } ) ;
10281062
10291063 panelViewStatesRef . current = {
@@ -1102,13 +1136,6 @@ export const Layout: React.FC<LayoutProps> = ({
11021136 continue ;
11031137 }
11041138
1105- for ( const existing of existingPanels ) {
1106- existing . api . updateParameters ( {
1107- panelId : panel . id ,
1108- panelKey : existing . id ,
1109- content : resolvePanelContent ( panel . id , existing . id ) ,
1110- } ) ;
1111- }
11121139 continue ;
11131140 }
11141141
@@ -1151,10 +1178,9 @@ export const Layout: React.FC<LayoutProps> = ({
11511178 panel . api . updateParameters ( {
11521179 panelId,
11531180 panelKey : panel . id ,
1154- content : resolvePanelContent ( panelId , panel . id ) ,
11551181 } ) ;
11561182 }
1157- } , [ resolvePanelContent ] ) ;
1183+ } , [ ] ) ;
11581184
11591185 const handleSelectPanelFromPicker = useCallback ( ( panelId : PanelId , pickerPanelId : string ) => {
11601186 const api = apiRef . current ;
@@ -1474,6 +1500,7 @@ export const Layout: React.FC<LayoutProps> = ({
14741500 const baseId = getPanelBaseId ( panel . id ) ;
14751501 if ( ! baseId ) return ;
14761502 onPanelActivated ?.( baseId , panel . id ) ;
1503+ restorePanelViewStates ( ) ;
14771504 } ) ,
14781505 api . onDidLayoutChange ( ( ) => {
14791506 if ( isRestoringLayoutRef . current ) {
@@ -1558,12 +1585,14 @@ export const Layout: React.FC<LayoutProps> = ({
15581585 < div className = "layout dockview-theme-dark" >
15591586 < div className = "layout-main" >
15601587 < LayoutViewStateContext . Provider value = { viewStateRegistry } >
1561- < DockviewReact
1562- components = { { layoutPanel : LayoutPanel , panelPicker : PanelPicker } }
1563- className = "layout-root"
1564- onReady = { handleReady }
1565- rightHeaderActionsComponent = { renderRightHeaderActions }
1566- />
1588+ < LayoutRenderContext . Provider value = { renderPanel } >
1589+ < DockviewReact
1590+ components = { DOCKVIEW_COMPONENTS }
1591+ className = "layout-root"
1592+ onReady = { handleReady }
1593+ rightHeaderActionsComponent = { renderRightHeaderActions }
1594+ />
1595+ </ LayoutRenderContext . Provider >
15671596 </ LayoutViewStateContext . Provider >
15681597 </ div >
15691598 < div className = "layout-toolbar" >
0 commit comments