diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..5386c20 --- /dev/null +++ b/changelog.md @@ -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.) \ No newline at end of file diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index e397473..e7ca23b 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -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.' } diff --git a/ts_web/elements/wcc-dashboard.ts b/ts_web/elements/wcc-dashboard.ts index 5bd3a0d..f7669c8 100644 --- a/ts_web/elements/wcc-dashboard.ts +++ b/ts_web/elements/wcc-dashboard.ts @@ -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; @@ -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) { 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; + } } }