11import { useEffect , useMemo , useRef , useCallback , useState } from "react" ;
22import { useDatamodelView , useDatamodelViewDispatch } from "@/contexts/DatamodelViewContext" ;
33import React from "react" ;
4- import { elementScroll , useVirtualizer , VirtualizerOptions } from '@tanstack/react-virtual' ;
4+ import { useVirtualizer } from '@tanstack/react-virtual' ;
55import { Section } from "./Section" ;
66import { useDatamodelData } from "@/contexts/DatamodelDataContext" ;
77import { AttributeType , EntityType , GroupType } from "@/lib/Types" ;
@@ -24,12 +24,10 @@ export function highlightMatch(text: string, search: string) {
2424
2525export const List = ( { setCurrentIndex } : IListProps ) => {
2626 const dispatch = useDatamodelViewDispatch ( ) ;
27- const { currentSection, loading } = useDatamodelView ( ) ;
27+ const { currentSection } = useDatamodelView ( ) ;
2828 const { groups, filtered, search } = useDatamodelData ( ) ;
2929 const { showSnackbar } = useSnackbar ( ) ;
3030 const parentRef = useRef < HTMLDivElement | null > ( null ) ;
31- const scrollTimeoutRef = useRef < NodeJS . Timeout > ( ) ;
32- const scrollingRef = React . useRef < number > ( )
3331 // used to relocate section after search/filter
3432 const [ sectionVirtualItem , setSectionVirtualItem ] = useState < string | null > ( null ) ;
3533
@@ -79,34 +77,6 @@ export const List = ({ setCurrentIndex }: IListProps) => {
7977 return items ;
8078 } , [ filtered , search , groups ] ) ;
8179
82- function easeInOutQuint ( t : number ) {
83- return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * -- t * t * t * t * t
84- }
85-
86- const scrollToFn : VirtualizerOptions < HTMLDivElement , HTMLElement > [ 'scrollToFn' ] =
87- React . useCallback ( ( offset , canSmooth , instance ) => {
88- const duration = 2000
89- const start = parentRef . current ?. scrollTop || 0
90- const startTime = ( scrollingRef . current = Date . now ( ) )
91-
92- const run = ( ) => {
93- if ( scrollingRef . current !== startTime ) return
94- const now = Date . now ( )
95- const elapsed = now - startTime
96- const progress = easeInOutQuint ( Math . min ( elapsed / duration , 1 ) )
97- const interpolated = start + ( offset - start ) * progress
98-
99- if ( elapsed < duration ) {
100- elementScroll ( interpolated , canSmooth , instance )
101- requestAnimationFrame ( run )
102- } else {
103- elementScroll ( interpolated , canSmooth , instance )
104- }
105- }
106-
107- requestAnimationFrame ( run )
108- } , [ ] )
109-
11080 const debouncedOnChange = debounce ( ( instance , sync ) => {
11181 if ( ! sync ) {
11282 dispatch ( { type : 'SET_LOADING_SECTION' , payload : null } ) ;
@@ -158,8 +128,11 @@ export const List = ({ setCurrentIndex }: IListProps) => {
158128 }
159129 }
160130
161- if ( mostVisibleEntity && currentSection !== mostVisibleEntity . entity . SchemaName ) {
131+ if ( mostVisibleEntity && ! search ) {
162132 setSectionVirtualItem ( mostVisibleEntity . entity . SchemaName ) ;
133+ }
134+
135+ if ( mostVisibleEntity && currentSection !== mostVisibleEntity . entity . SchemaName ) {
163136 updateURL ( { query : { group : mostVisibleEntity . group . Name , section : mostVisibleEntity . entity . SchemaName } } ) ;
164137 dispatch ( { type : "SET_CURRENT_GROUP" , payload : mostVisibleEntity . group . Name } ) ;
165138 dispatch ( { type : "SET_CURRENT_SECTION" , payload : mostVisibleEntity . entity . SchemaName } ) ;
@@ -176,15 +149,10 @@ export const List = ({ setCurrentIndex }: IListProps) => {
176149 if ( ! item ) return 200 ;
177150 return item . type === 'group' ? 100 : 500 ;
178151 } ,
179- scrollToFn,
180152 onChange : debouncedOnChange ,
181153 } ) ;
182154
183155 const scrollToSection = useCallback ( ( sectionId : string ) => {
184- if ( scrollTimeoutRef . current ) {
185- clearTimeout ( scrollTimeoutRef . current ) ;
186- }
187-
188156 const sectionIndex = flatItems . findIndex ( item =>
189157 item . type === 'entity' && item . entity . SchemaName === sectionId
190158 ) ;
@@ -195,16 +163,13 @@ export const List = ({ setCurrentIndex }: IListProps) => {
195163 }
196164
197165 rowVirtualizer . scrollToIndex ( sectionIndex , {
198- align : 'start'
166+ align : 'start' ,
167+ behavior : 'smooth'
199168 } ) ;
200169
201170 } , [ flatItems ] ) ;
202171
203172 const scrollToGroup = useCallback ( ( groupName : string ) => {
204- if ( scrollTimeoutRef . current ) {
205- clearTimeout ( scrollTimeoutRef . current ) ;
206- }
207-
208173 const groupIndex = flatItems . findIndex ( item =>
209174 item . type === 'group' && item . group . Name === groupName
210175 ) ;
@@ -215,7 +180,8 @@ export const List = ({ setCurrentIndex }: IListProps) => {
215180 }
216181
217182 rowVirtualizer . scrollToIndex ( groupIndex , {
218- align : 'start'
183+ align : 'start' ,
184+ behavior : 'smooth'
219185 } ) ;
220186 } , [ flatItems ] ) ;
221187
@@ -229,12 +195,6 @@ export const List = ({ setCurrentIndex }: IListProps) => {
229195 dispatch ( { type : 'SET_SCROLL_TO_SECTION' , payload : scrollToSection } ) ;
230196 dispatch ( { type : 'SET_SCROLL_TO_GROUP' , payload : scrollToGroup } ) ;
231197 dispatch ( { type : 'SET_RESTORE_SECTION' , payload : restoreSection } ) ;
232-
233- return ( ) => {
234- if ( scrollTimeoutRef . current ) {
235- clearTimeout ( scrollTimeoutRef . current ) ;
236- }
237- } ;
238198 } , [ dispatch , scrollToSection , scrollToGroup ] ) ;
239199
240200 // Callback to handle section content changes (for tab switches, expansions, etc.)
@@ -250,24 +210,6 @@ export const List = ({ setCurrentIndex }: IListProps) => {
250210 return (
251211 < div ref = { parentRef } style = { { height : 'calc(100vh - var(--layout-header-desktop-height))' , overflow : 'auto' } } className = "p-6 relative no-scrollbar" >
252212
253- { /* Show skeleton loading state only when initially loading */ }
254- { flatItems . length === 0 && loading && ( ! search || search . length < 3 ) && (
255- < div className = "space-y-8" >
256- { [ ...Array ( 5 ) ] . map ( ( _ , i ) => (
257- < div key = { i } className = "bg-white rounded-lg border border-gray-300 shadow-md animate-pulse" >
258- < div className = "h-32 p-6 flex flex-col" >
259- < div className = "h-6 bg-gray-200 rounded w-1/3 mb-4" > </ div >
260- < div className = "h-4 bg-gray-200 rounded w-1/2" > </ div >
261- </ div >
262- < div className = "p-4 border-t" >
263- < div className = "h-4 bg-gray-200 rounded w-full mb-3" > </ div >
264- < div className = "h-4 bg-gray-200 rounded w-5/6" > </ div >
265- </ div >
266- </ div >
267- ) ) }
268- </ div >
269- ) }
270-
271213 { /* Show no results message when searching but no items found */ }
272214 { flatItems . length === 0 && search && search . length >= 3 && (
273215 < div className = "flex flex-col items-center justify-center h-64 text-gray-500" >
0 commit comments