fix(properties): enhance element detection in properties panel with recursive search and retry mechanism
This commit is contained in:
@ -3,12 +3,14 @@
|
||||
"version": "1.0.90",
|
||||
"private": false,
|
||||
"description": "A set of web component tools for creating element catalogues, enabling the structured development and documentation of custom elements and pages.",
|
||||
"main": "dist_ts_web/index.js",
|
||||
"typings": "dist_ts_web/index.d.ts",
|
||||
"exports": {
|
||||
".": "./dist_ts_web/index.js",
|
||||
"./demoTools": "./dist_ts_demotools"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "(npm run build)",
|
||||
"build": "(tsbuild element --web --allowimplicitany && tsbundle element)",
|
||||
"build": "(tsbuild tsfolders --allowimplicitany && tsbundle element)",
|
||||
"watch": "tswatch element",
|
||||
"buildDocs": "tsdoc"
|
||||
},
|
||||
|
@ -1 +1,24 @@
|
||||
|
||||
# Project Hints and Findings
|
||||
|
||||
## Properties Panel Element Detection Issue (Fixed)
|
||||
|
||||
### Problem
|
||||
The properties panel had timing issues detecting rendered elements because:
|
||||
1. Elements are rendered asynchronously via lit's `render()` function in the dashboard component
|
||||
2. The properties panel tried to find elements immediately without waiting for render completion
|
||||
3. Element search only looked at direct children of the viewport, missing nested elements or those inside shadow DOM
|
||||
|
||||
### Solution Implemented
|
||||
1. Added a 100ms initial delay to allow render completion
|
||||
2. Implemented recursive element search that:
|
||||
- Searches through nested children up to 5 levels deep
|
||||
- Checks shadow roots of elements
|
||||
- Handles complex DOM structures
|
||||
3. Added retry mechanism with up to 5 attempts (200ms between retries)
|
||||
4. Improved error messages to show retry count
|
||||
|
||||
### Code Flow
|
||||
1. Dashboard renders element demo into viewport using `render(anonItem.demo(), viewport)`
|
||||
2. Properties panel waits, then searches recursively for the element instance
|
||||
3. If not found, retries with delays to handle async rendering
|
||||
4. Once found, extracts and displays element properties
|
30
readme.plan.md
Normal file
30
readme.plan.md
Normal file
@ -0,0 +1,30 @@
|
||||
# Fix Properties Panel Element Detection
|
||||
|
||||
To fix the element detection issue, reread CLAUDE.md first.
|
||||
|
||||
## Problem Analysis
|
||||
The properties panel has timing issues detecting rendered elements because:
|
||||
1. Elements are rendered asynchronously via lit's `render()` in the dashboard
|
||||
2. Properties panel tries to find elements immediately without waiting for render completion
|
||||
3. Element search only looks at direct children, missing nested/shadow DOM elements
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### 1. Add proper synchronization
|
||||
- Add a delay or await render completion before element detection
|
||||
- Use MutationObserver or lit's updateComplete promises
|
||||
|
||||
### 2. Improve element search algorithm
|
||||
- Search recursively through all descendants, not just direct children
|
||||
- Handle shadow DOM boundaries properly
|
||||
- Support elements wrapped in containers
|
||||
|
||||
### 3. Add retry mechanism
|
||||
- If element not found, retry after a delay
|
||||
- Add maximum retry attempts to prevent infinite loops
|
||||
- Clear error state when element is eventually found
|
||||
|
||||
## Code Changes Required
|
||||
1. Modify `wcc-properties.ts` createProperties() method
|
||||
2. Add element search utility function
|
||||
3. Improve error handling and user feedback
|
0
ts_demotools/demotools.ts
Normal file
0
ts_demotools/demotools.ts
Normal file
0
ts_demotools/index.ts
Normal file
0
ts_demotools/index.ts
Normal file
1
ts_demotools/plugins.ts
Normal file
1
ts_demotools/plugins.ts
Normal file
@ -0,0 +1 @@
|
||||
import {} from '@design.estate/dees-element';
|
@ -226,6 +226,31 @@ export class WccProperties extends DeesElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private async findElementRecursively(container: Element, elementClass: any, maxDepth: number = 5): Promise<HTMLElement | null> {
|
||||
if (maxDepth <= 0) return null;
|
||||
|
||||
// Check direct children
|
||||
for (const child of Array.from(container.children)) {
|
||||
if (child instanceof elementClass) {
|
||||
return child as HTMLElement;
|
||||
}
|
||||
}
|
||||
|
||||
// Check shadow roots of children
|
||||
for (const child of Array.from(container.children)) {
|
||||
if (child.shadowRoot) {
|
||||
const found = await this.findElementRecursively(child.shadowRoot as any, elementClass, maxDepth - 1);
|
||||
if (found) return found;
|
||||
}
|
||||
|
||||
// Also check nested children
|
||||
const found = await this.findElementRecursively(child, elementClass, maxDepth - 1);
|
||||
if (found) return found;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async createProperties() {
|
||||
console.log('creating properties for:');
|
||||
console.log(this.selectedItem);
|
||||
@ -275,15 +300,30 @@ export class WccProperties extends DeesElement {
|
||||
}
|
||||
console.log(anonItem.elementProperties);
|
||||
const wccFrame = await this.dashboardRef.wccFrame;
|
||||
let firstFoundInstantiatedElement: HTMLElement;
|
||||
for (const element of Array.from((await wccFrame.getViewportElement()).children)) {
|
||||
if (element instanceof (this.selectedItem as any)) {
|
||||
firstFoundInstantiatedElement = element as HTMLElement;
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for render to complete
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
|
||||
// Try to find the element with recursive search
|
||||
const viewport = await wccFrame.getViewportElement();
|
||||
let firstFoundInstantiatedElement: HTMLElement = await this.findElementRecursively(
|
||||
viewport,
|
||||
this.selectedItem as any
|
||||
);
|
||||
|
||||
// Retry logic if element not found
|
||||
let retries = 0;
|
||||
while (!firstFoundInstantiatedElement && retries < 5) {
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
firstFoundInstantiatedElement = await this.findElementRecursively(
|
||||
viewport,
|
||||
this.selectedItem as any
|
||||
);
|
||||
retries++;
|
||||
}
|
||||
|
||||
if (!firstFoundInstantiatedElement) {
|
||||
this.warning = `no first instantiated element found for >>${anonItem.name}<<`;
|
||||
this.warning = `no first instantiated element found for >>${anonItem.name}<< after ${retries} retries`;
|
||||
return;
|
||||
}
|
||||
const classProperties: Map<string, any> = anonItem.elementProperties;
|
||||
|
Reference in New Issue
Block a user