fix(demotools): enhance runAfterRender to provide full DOM API access and improve element selection
This commit is contained in:
		| @@ -34,16 +34,22 @@ import * as demoTools from '@design.estate/dees-wcctools/demotools'; | ||||
|  | ||||
| // In your demo function: | ||||
| demo: () => html` | ||||
|   <dees-demowrapper .runAfterRender=${(children: HTMLCollection) => { | ||||
|     // Access all slotted elements | ||||
|     const firstElement = children[0] as HTMLElement; | ||||
|     firstElement.setAttribute('data-demo', 'true'); | ||||
|     console.log('All slotted elements:', children); | ||||
|   <dees-demowrapper .runAfterRender=${(wrapper) => { | ||||
|     // Use querySelector for specific elements | ||||
|     const myElement = wrapper.querySelector('my-custom-element'); | ||||
|     myElement?.setAttribute('data-demo', 'true'); | ||||
|      | ||||
|     // Work with multiple elements | ||||
|     Array.from(children).forEach(child => { | ||||
|       console.log('Element rendered:', child); | ||||
|     // Access all children | ||||
|     console.log('All children:', wrapper.children); | ||||
|      | ||||
|     // Use querySelectorAll for multiple elements | ||||
|     wrapper.querySelectorAll('div').forEach(div => { | ||||
|       console.log('Found div:', div); | ||||
|     }); | ||||
|      | ||||
|     // Full DOM API available | ||||
|     const firstChild = wrapper.firstElementChild; | ||||
|     const hasClass = wrapper.querySelector('.my-class'); | ||||
|   }}> | ||||
|     <my-custom-element></my-custom-element> | ||||
|     <div>Additional content</div> | ||||
| @@ -53,7 +59,8 @@ demo: () => html` | ||||
|  | ||||
| **Features:** | ||||
| - Wraps demo elements without affecting layout (uses `display: contents`) | ||||
| - Provides access to ALL slotted elements via HTMLCollection after mounting | ||||
| - Provides the wrapper element itself with full DOM API access | ||||
| - Use querySelector/querySelectorAll for powerful element selection | ||||
| - Access children via wrapper.children property | ||||
| - Supports async operations in runAfterRender callback | ||||
| - Automatically handles timing to ensure elements are fully rendered | ||||
| - Can handle multiple slotted elements, not just the first one | ||||
| - Automatically handles timing to ensure elements are fully rendered | ||||
							
								
								
									
										42
									
								
								readme.md
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								readme.md
									
									
									
									
									
								
							| @@ -183,23 +183,24 @@ import * as demoTools from '@design.estate/dees-wcctools/demotools'; | ||||
| @customElement('my-component') | ||||
| export class MyComponent extends DeesElement { | ||||
|   public static demo = () => html` | ||||
|     <dees-demowrapper .runAfterRender=${async (children: HTMLCollection) => { | ||||
|       // Access all slotted elements | ||||
|       console.log('Slotted elements:', children.length); | ||||
|     <dees-demowrapper .runAfterRender=${async (wrapper) => { | ||||
|       // Use querySelector to find specific elements | ||||
|       const myComponent = wrapper.querySelector('my-component') as MyComponent; | ||||
|       console.log('Component found:', myComponent); | ||||
|        | ||||
|       // Access specific element (e.g., first child) | ||||
|       const myComponent = children[0] as MyComponent; | ||||
|       console.log('Component mounted:', myComponent); | ||||
|       // Access all children via wrapper.children | ||||
|       console.log('Total children:', wrapper.children.length); | ||||
|        | ||||
|       // Use querySelectorAll for multiple elements | ||||
|       const allDivs = wrapper.querySelectorAll('div'); | ||||
|       console.log('Found divs:', allDivs.length); | ||||
|        | ||||
|       // Simulate user interactions | ||||
|       myComponent.value = 'Test value'; | ||||
|       await myComponent.updateComplete; | ||||
|        | ||||
|       // Trigger methods | ||||
|       myComponent.handleClick(); | ||||
|        | ||||
|       // Work with multiple elements if present | ||||
|       Array.from(children).forEach((child, index) => { | ||||
|       // Work with all children | ||||
|       Array.from(wrapper.children).forEach((child, index) => { | ||||
|         console.log(`Child ${index}:`, child.tagName); | ||||
|       }); | ||||
|     }}> | ||||
| @@ -309,12 +310,18 @@ For complex property types, implement custom logic in your demo: | ||||
|  | ||||
| ```typescript | ||||
| public static demo = () => html` | ||||
|   <dees-demowrapper .runAfterRender=${(children) => { | ||||
|     // Set up complex property handling for all children | ||||
|     Array.from(children).forEach(child => { | ||||
|       child.addEventListener('property-change', (e) => { | ||||
|   <dees-demowrapper .runAfterRender=${(wrapper) => { | ||||
|     // Use querySelector to target specific elements | ||||
|     const component = wrapper.querySelector('my-component'); | ||||
|     if (component) { | ||||
|       component.addEventListener('property-change', (e) => { | ||||
|         console.log('Property changed:', e.detail); | ||||
|       }); | ||||
|     } | ||||
|      | ||||
|     // Or handle all elements of a type | ||||
|     wrapper.querySelectorAll('my-component').forEach(el => { | ||||
|       el.addEventListener('click', () => console.log('Clicked!')); | ||||
|     }); | ||||
|   }}> | ||||
|     <my-component></my-component> | ||||
| @@ -354,9 +361,10 @@ Initialize the WCC Tools dashboard. | ||||
| Component for wrapping demos with post-render logic. | ||||
|  | ||||
| - `runAfterRender`: Function called after the wrapped elements render | ||||
| - Receives the complete HTMLCollection of all slotted elements | ||||
| - Receives the wrapper element itself, providing full DOM API access | ||||
| - Use `wrapper.querySelector()` and `wrapper.querySelectorAll()` for element selection | ||||
| - Access children via `wrapper.children` property | ||||
| - Supports async operations | ||||
| - Access individual elements via array index or Array.from() | ||||
|  | ||||
| ## Browser Support | ||||
| - Chrome/Edge (latest) | ||||
|   | ||||
| @@ -55,8 +55,10 @@ The properties panel has timing issues detecting rendered elements because: | ||||
| # Enhanced DemoWrapper (COMPLETED) | ||||
|  | ||||
| ## Modified runAfterRender callback: | ||||
| - Now receives HTMLCollection of ALL slotted elements instead of just the first one | ||||
| - Allows access to complete slotted DOM structure | ||||
| - Now receives the wrapper element itself instead of just children | ||||
| - Provides full DOM API access (querySelector, querySelectorAll, etc.) | ||||
| - querySelector works on slotted content (light DOM children) | ||||
| - Access children via wrapper.children property | ||||
| - Updated documentation with correct import path (lowercase 'demotools') | ||||
| - Examples show how to work with multiple slotted elements | ||||
| - Maintains backward compatibility by accessing elements via index | ||||
| - Examples show how to use querySelector for powerful element selection | ||||
| - Added clarifying comment about querySelector working on slotted content | ||||
| @@ -3,7 +3,7 @@ import { DeesElement, customElement, html, css, property, type TemplateResult } | ||||
| @customElement('dees-demowrapper') | ||||
| export class DeesDemoWrapper extends DeesElement { | ||||
|   @property({ attribute: false }) | ||||
|   public runAfterRender: (children: HTMLCollection) => void | Promise<void>; | ||||
|   public runAfterRender: (wrapperElement: DeesDemoWrapper) => void | Promise<void>; | ||||
|  | ||||
|   public static styles = [ | ||||
|     css` | ||||
| @@ -25,12 +25,13 @@ export class DeesDemoWrapper extends DeesElement { | ||||
|     // Wait a bit for slotted content to render | ||||
|     await new Promise(resolve => setTimeout(resolve, 50)); | ||||
|      | ||||
|     // Get all slotted elements | ||||
|     const slottedElements = this.children; | ||||
|     if (slottedElements.length > 0 && this.runAfterRender) { | ||||
|       // Call the runAfterRender function with all slotted elements | ||||
|     // Check if there are slotted elements and runAfterRender is defined | ||||
|     if (this.children.length > 0 && this.runAfterRender) { | ||||
|       // Call the runAfterRender function with the wrapper element itself | ||||
|       // Note: querySelector/querySelectorAll will work on slotted content | ||||
|       // because slotted elements remain in the light DOM as children | ||||
|       try { | ||||
|         await this.runAfterRender(slottedElements); | ||||
|         await this.runAfterRender(this); | ||||
|       } catch (error) { | ||||
|         console.error('Error in runAfterRender:', error); | ||||
|       } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user