fix(dashboard): Fix scroll state preservation in dashboard by tracking frame and sidebar scroll positions and updating the URL accordingly.
This commit is contained in:
		
							
								
								
									
										36
									
								
								changelog.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								changelog.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| # Changelog | ||||
|  | ||||
| ## 2025-06-26 - 1.0.99 - fix(dashboard) | ||||
| Fix scroll state preservation in dashboard by tracking frame and sidebar scroll positions and updating the URL accordingly. | ||||
|  | ||||
| - Added frameScrollY and sidebarScrollY properties to capture scroll positions. | ||||
| - Set up scroll listeners on wcc-frame and wcc-sidebar to update scroll state. | ||||
| - Implemented debounced updates to modify the URL with current scroll positions without navigation. | ||||
| - Restored scroll positions from URL query parameters during initialization. | ||||
|  | ||||
| ## 2025-06-16 - 1.0.97 - properties-panel | ||||
| - Improve element detection timing and value handling in properties panel | ||||
|  | ||||
| ## 2025-06-16 - 1.0.96 - properties-panel | ||||
| - Enhance element detection and error handling for nested structures | ||||
|  | ||||
| ## 2025-06-16 - 1.0.95 - package | ||||
| - Correct path for demotools export in package.json | ||||
|  | ||||
| ## 2025-06-16 - 1.0.94 - demotools | ||||
| - Enhance runAfterRender to provide full DOM API access and improve element selection | ||||
|  | ||||
| ## 2025-06-16 - 1.0.92 - demotools | ||||
| - Update DeesDemoWrapper to handle multiple slotted elements in runAfterRender callback | ||||
|  | ||||
| ## 2025-06-16 - 1.0.91 - readme | ||||
| - Update documentation with comprehensive overview, quick start guide, and detailed feature descriptions | ||||
|  | ||||
| ## 2025-06-16 - 1.0.90 - demo/properties/refactor | ||||
| - Add DeesDemoWrapper component for enhanced demo element handling | ||||
| - Enhance element detection in properties panel with recursive search and retry mechanism | ||||
| - Refactor code structure for improved readability and maintainability | ||||
|  | ||||
| ## 2024-05-06 to 2020-05-10 - 1.0.89–1.0.17 - core | ||||
| - Over a series of releases, trivial core fixes and updates were applied. | ||||
| - (Note: Version 1.0.87 also included an update to the documentation.) | ||||
| @@ -1,8 +1,8 @@ | ||||
| /** | ||||
|  * autocreated commitinfo by @pushrocks/commitinfo | ||||
|  * autocreated commitinfo by @push.rocks/commitinfo | ||||
|  */ | ||||
| export const commitinfo = { | ||||
|   name: '@design.estate/dees-wcctools', | ||||
|   version: '1.0.90', | ||||
|   version: '1.0.99', | ||||
|   description: 'A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.' | ||||
| } | ||||
|   | ||||
| @@ -38,6 +38,12 @@ export class WccDashboard extends DeesElement { | ||||
|   @property() | ||||
|   public warning: string = null; | ||||
|    | ||||
|   @property() | ||||
|   public frameScrollY: number = 0; | ||||
|    | ||||
|   @property() | ||||
|   public sidebarScrollY: number = 0; | ||||
|    | ||||
|   @queryAsync('wcc-frame') | ||||
|   public wccFrame: Promise<WccFrame>; | ||||
|  | ||||
| @@ -113,6 +119,12 @@ export class WccDashboard extends DeesElement { | ||||
|  | ||||
|   public async firstUpdated() { | ||||
|     this.domtools = await plugins.deesDomtools.DomTools.setupDomTools(); | ||||
|      | ||||
|     // Set up scroll listeners after DOM is ready | ||||
|     setTimeout(() => { | ||||
|       this.setupScrollListeners(); | ||||
|     }, 500); | ||||
|      | ||||
|     this.domtools.router.on( | ||||
|       '/wcctools-route/:itemType/:itemName/:viewport/:theme', | ||||
|       async (routeInfo) => { | ||||
| @@ -125,6 +137,25 @@ export class WccDashboard extends DeesElement { | ||||
|         } else if (routeInfo.params.itemType === 'page') { | ||||
|           this.selectedItem = this.pages[routeInfo.params.itemName]; | ||||
|         } | ||||
|          | ||||
|         // Restore scroll positions from query parameters | ||||
|         if (routeInfo.queryParams) { | ||||
|           const frameScrollY = routeInfo.queryParams.frameScrollY; | ||||
|           const sidebarScrollY = routeInfo.queryParams.sidebarScrollY; | ||||
|            | ||||
|           if (frameScrollY) { | ||||
|             this.frameScrollY = parseInt(frameScrollY); | ||||
|           } | ||||
|           if (sidebarScrollY) { | ||||
|             this.sidebarScrollY = parseInt(sidebarScrollY); | ||||
|           } | ||||
|            | ||||
|           // Apply scroll positions after a short delay to ensure DOM is ready | ||||
|           setTimeout(() => { | ||||
|             this.applyScrollPositions(); | ||||
|           }, 100); | ||||
|         } | ||||
|          | ||||
|         const domtoolsInstance = await plugins.deesDomtools.elementBasic.setup(); | ||||
|         this.selectedTheme === 'bright' | ||||
|           ? domtoolsInstance.themeManager.goBright() | ||||
| @@ -136,7 +167,6 @@ export class WccDashboard extends DeesElement { | ||||
|   public async updated(changedPropertiesArg: Map<string, any>) { | ||||
|     this.domtools = await plugins.deesDomtools.DomTools.setupDomTools(); | ||||
|     await this.domtools.router._handleRouteState(); | ||||
|     const storeElement = this.selectedItem; | ||||
|     const wccFrame: WccFrame = this.shadowRoot.querySelector('wcc-frame'); | ||||
|  | ||||
|     if (changedPropertiesArg.has('selectedItemName')) { | ||||
| @@ -173,8 +203,82 @@ export class WccDashboard extends DeesElement { | ||||
|   } | ||||
|  | ||||
|   public buildUrl() { | ||||
|     this.domtools.router.pushUrl( | ||||
|       `/wcctools-route/${this.selectedType}/${this.selectedItemName}/${this.selectedViewport}/${this.selectedTheme}` | ||||
|     ); | ||||
|     const baseUrl = `/wcctools-route/${this.selectedType}/${this.selectedItemName}/${this.selectedViewport}/${this.selectedTheme}`; | ||||
|     const queryParams = new URLSearchParams(); | ||||
|      | ||||
|     if (this.frameScrollY > 0) { | ||||
|       queryParams.set('frameScrollY', this.frameScrollY.toString()); | ||||
|     } | ||||
|     if (this.sidebarScrollY > 0) { | ||||
|       queryParams.set('sidebarScrollY', this.sidebarScrollY.toString()); | ||||
|     } | ||||
|      | ||||
|     const queryString = queryParams.toString(); | ||||
|     const fullUrl = queryString ? `${baseUrl}?${queryString}` : baseUrl; | ||||
|      | ||||
|     this.domtools.router.pushUrl(fullUrl); | ||||
|   } | ||||
|    | ||||
|   private scrollUpdateTimeout: NodeJS.Timeout; | ||||
|    | ||||
|   public async setupScrollListeners() { | ||||
|     const wccFrame = await this.wccFrame; | ||||
|     const wccSidebar = this.shadowRoot.querySelector('wcc-sidebar'); | ||||
|      | ||||
|     if (wccFrame) { | ||||
|       // The frame element itself is the scrollable container | ||||
|       wccFrame.addEventListener('scroll', () => { | ||||
|         this.frameScrollY = wccFrame.scrollTop; | ||||
|         this.debouncedScrollUpdate(); | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     if (wccSidebar) { | ||||
|       // The sidebar element itself is the scrollable container | ||||
|       wccSidebar.addEventListener('scroll', () => { | ||||
|         this.sidebarScrollY = wccSidebar.scrollTop; | ||||
|         this.debouncedScrollUpdate(); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
|    | ||||
|   private debouncedScrollUpdate() { | ||||
|     clearTimeout(this.scrollUpdateTimeout); | ||||
|     this.scrollUpdateTimeout = setTimeout(() => { | ||||
|       this.updateUrlWithScrollState(); | ||||
|     }, 300); | ||||
|   } | ||||
|    | ||||
|   private updateUrlWithScrollState() { | ||||
|     const baseUrl = `/wcctools-route/${this.selectedType}/${this.selectedItemName}/${this.selectedViewport}/${this.selectedTheme}`; | ||||
|     const queryParams = new URLSearchParams(); | ||||
|      | ||||
|     if (this.frameScrollY > 0) { | ||||
|       queryParams.set('frameScrollY', this.frameScrollY.toString()); | ||||
|     } | ||||
|     if (this.sidebarScrollY > 0) { | ||||
|       queryParams.set('sidebarScrollY', this.sidebarScrollY.toString()); | ||||
|     } | ||||
|      | ||||
|     const queryString = queryParams.toString(); | ||||
|     const fullUrl = queryString ? `${baseUrl}?${queryString}` : baseUrl; | ||||
|      | ||||
|     // Use replaceState to update URL without navigation | ||||
|     window.history.replaceState(null, '', fullUrl); | ||||
|   } | ||||
|    | ||||
|   public async applyScrollPositions() { | ||||
|     const wccFrame = await this.wccFrame; | ||||
|     const wccSidebar = this.shadowRoot.querySelector('wcc-sidebar'); | ||||
|      | ||||
|     if (wccFrame && this.frameScrollY > 0) { | ||||
|       // The frame element itself is the scrollable container | ||||
|       wccFrame.scrollTop = this.frameScrollY; | ||||
|     } | ||||
|      | ||||
|     if (wccSidebar && this.sidebarScrollY > 0) { | ||||
|       // The sidebar element itself is the scrollable container | ||||
|       wccSidebar.scrollTop = this.sidebarScrollY; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user