@@ -4,7 +4,6 @@ import Collection from '../collection/Base.mjs';
44import GridBody from './Body.mjs' ;
55import ScrollManager from './ScrollManager.mjs' ;
66import Store from '../data/Store.mjs' ;
7- import VerticalScrollbar from './VerticalScrollbar.mjs' ;
87import FooterToolbar from './footer/Toolbar.mjs' ;
98import * as column from './column/_export.mjs' ;
109import * as header from './header/_export.mjs' ;
@@ -16,7 +15,6 @@ import {isDescriptor} from '../core/ConfigSymbols.mjs';
1615 * `Neo.grid.Container` orchestrates the entire Grid component. It uses a composite architecture consisting of:
1716 * 1. `headerToolbar` ({@link Neo.grid.header.Toolbar}): Manages column headers, sorting, and filtering UI.
1817 * 2. `body` ({@link Neo.grid.Body}): The scrollable area containing the data rows.
19- * 3. `scrollbar` ({@link Neo.grid.VerticalScrollbar}): A virtualized scrollbar for handling large datasets.
2018 *
2119 * Key features include:
2220 * - **Virtual Scrolling:** Only renders visible rows and columns (plus a small buffer) for high performance with large datasets.
@@ -170,11 +168,7 @@ class GridContainer extends BaseContainer {
170168 * @reactive
171169 */
172170 rowHeight_ : 32 ,
173- /**
174- * @member {Neo.grid.Scrollbar|null} scrollbar=null
175- * @protected
176- */
177- scrollbar : null ,
171+
178172 /**
179173 * @member {Boolean} showHeaderFilters_=false
180174 * @reactive
@@ -305,18 +299,6 @@ class GridContainer extends BaseContainer {
305299 me . items . push ( me . footerToolbar )
306300 }
307301
308- me . scrollbar = Neo . create ( {
309- module : VerticalScrollbar ,
310- appName,
311- parentId : me . id ,
312- rowHeight,
313- store,
314- theme : me . theme ,
315- windowId
316- } ) ;
317-
318- me . vdom . cn . push ( me . scrollbar . createVdomReference ( ) )
319-
320302 me . vdom . id = me . getWrapperId ( ) ;
321303
322304 me . _columns = me . createColumns ( me . columns ) ;
@@ -450,15 +432,11 @@ class GridContainer extends BaseContainer {
450432 */
451433 afterSetRowHeight ( value , oldValue ) {
452434 if ( value > 0 ) {
453- let { body, scrollbar} = this ;
454-
455- if ( scrollbar ) {
456- scrollbar . rowHeight = value
457- }
435+ let { body, bodyEnd, bodyStart} = this ;
458436
459- if ( body ) {
460- body . rowHeight = value
461- }
437+ if ( body ) body . rowHeight = value ;
438+ if ( bodyStart ) bodyStart . rowHeight = value ;
439+ if ( bodyEnd ) bodyEnd . rowHeight = value ;
462440 }
463441 }
464442
@@ -519,9 +497,9 @@ class GridContainer extends BaseContainer {
519497 oldValue ?. un ( listeners ) ;
520498
521499 // in case we dynamically change the store, grid.Body needs to get the new reference
522- if ( me . body ) {
523- me . body . store = value
524- }
500+ if ( me . body ) me . body . store = value ;
501+ if ( me . bodyStart ) me . bodyStart . store = value ;
502+ if ( me . bodyEnd ) me . bodyEnd . store = value
525503
526504 if ( me . footerToolbar && me . footerToolbar . store !== value ) {
527505 me . footerToolbar . store = value
@@ -537,8 +515,10 @@ class GridContainer extends BaseContainer {
537515 * @protected
538516 */
539517 afterSetUseInternalId ( value , oldValue ) {
540- if ( oldValue !== undefined && this . body ) {
541- this . body . useInternalId = value
518+ if ( oldValue !== undefined ) {
519+ if ( this . body ) this . body . useInternalId = value ;
520+ if ( this . bodyStart ) this . bodyStart . useInternalId = value ;
521+ if ( this . bodyEnd ) this . bodyEnd . useInternalId = value ;
542522 }
543523 }
544524
@@ -1160,10 +1140,14 @@ class GridContainer extends BaseContainer {
11601140 await me . timeout ( 100 ) ;
11611141 await me . passSizeToBody ( silent )
11621142 } else {
1163- me . body [ silent ? 'setSilent' : 'set' ] ( {
1143+ let config = {
11641144 availableHeight : containerRect . height - headerRect . height - ( footerRect ?. height || 0 ) ,
11651145 containerWidth : containerRect . width
1166- } )
1146+ } ;
1147+
1148+ me . body [ silent ? 'setSilent' : 'set' ] ( config ) ;
1149+ me . bodyStart && me . bodyStart [ silent ? 'setSilent' : 'set' ] ( config ) ;
1150+ me . bodyEnd && me . bodyEnd [ silent ? 'setSilent' : 'set' ] ( config )
11671151 }
11681152 }
11691153
@@ -1234,6 +1218,40 @@ class GridContainer extends BaseContainer {
12341218 }
12351219 }
12361220
1221+ /**
1222+ * Pushes synchronized scrolling coordinates (like startIndex) into all active bodies
1223+ * @param {Number } scrollTop
1224+ */
1225+ syncBodies ( scrollTop ) {
1226+ let me = this ,
1227+ { body, bodyEnd, bodyStart, scrollManager} = me ,
1228+ { bufferRowRange, rowHeight} = body ,
1229+ newStartIndex = Math . floor ( scrollTop / rowHeight ) ;
1230+
1231+ let updateBody = _body => {
1232+ _body . skipCreateViewData = true ;
1233+
1234+ _body . set ( {
1235+ scrollLeft : scrollManager . scrollLeft , // Horizontal sync applies from scrollManager state
1236+ scrollTop : scrollTop
1237+ } ) ;
1238+
1239+ if ( Math . abs ( _body . startIndex - newStartIndex ) >= bufferRowRange ) {
1240+ _body . startIndex = newStartIndex
1241+ } else {
1242+ _body . visibleRows [ 0 ] = newStartIndex ;
1243+ _body . visibleRows [ 1 ] = newStartIndex + _body . availableRows
1244+ }
1245+
1246+ _body . skipCreateViewData = false ;
1247+ _body . createViewData ( ) ;
1248+ } ;
1249+
1250+ updateBody ( body ) ;
1251+ bodyStart && updateBody ( bodyStart ) ;
1252+ bodyEnd && updateBody ( bodyEnd )
1253+ }
1254+
12371255 /**
12381256 * Serializes the instance into a JSON-compatible object for the Neural Link.
12391257 * @returns {Object }
@@ -1249,7 +1267,7 @@ class GridContainer extends BaseContainer {
12491267 footerToolbar : me . footerToolbar ?. toJSON ( ) ,
12501268 headerToolbar : me . headerToolbar ?. toJSON ( ) ,
12511269 rowHeight : me . rowHeight ,
1252- scrollbar : me . scrollbar ?. toJSON ( ) ,
1270+
12531271 scrollManager : me . scrollManager ?. toJSON ( ) ,
12541272 showHeaderFilters : me . showHeaderFilters ,
12551273 sortable : me . sortable ,
0 commit comments