From d4fce8a939fa137074c308cf06055dbbd391f32c Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Mon, 16 Jun 2025 14:45:19 +0000 Subject: [PATCH] fix(demotools): enhance runAfterRender to provide full DOM API access and improve element selection --- readme.hints.md | 29 +++++++++++++++++---------- readme.md | 42 +++++++++++++++++++++++---------------- readme.plan.md | 10 ++++++---- ts_demotools/demotools.ts | 13 ++++++------ 4 files changed, 56 insertions(+), 38 deletions(-) diff --git a/readme.hints.md b/readme.hints.md index fc90a20..f7b50e8 100644 --- a/readme.hints.md +++ b/readme.hints.md @@ -34,16 +34,22 @@ import * as demoTools from '@design.estate/dees-wcctools/demotools'; // In your demo function: demo: () => html` - { - // Access all slotted elements - const firstElement = children[0] as HTMLElement; - firstElement.setAttribute('data-demo', 'true'); - console.log('All slotted elements:', children); + { + // 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'); }}>
Additional content
@@ -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 \ No newline at end of file +- Automatically handles timing to ensure elements are fully rendered \ No newline at end of file diff --git a/readme.md b/readme.md index 442534c..c638ce4 100644 --- a/readme.md +++ b/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` - { - // Access all slotted elements - console.log('Slotted elements:', children.length); + { + // 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` - { - // Set up complex property handling for all children - Array.from(children).forEach(child => { - child.addEventListener('property-change', (e) => { + { + // 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!')); }); }}> @@ -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) diff --git a/readme.plan.md b/readme.plan.md index 47a9f28..feb47d3 100644 --- a/readme.plan.md +++ b/readme.plan.md @@ -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 \ No newline at end of file +- Examples show how to use querySelector for powerful element selection +- Added clarifying comment about querySelector working on slotted content \ No newline at end of file diff --git a/ts_demotools/demotools.ts b/ts_demotools/demotools.ts index 0bc66c7..61d4c23 100644 --- a/ts_demotools/demotools.ts +++ b/ts_demotools/demotools.ts @@ -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; + public runAfterRender: (wrapperElement: DeesDemoWrapper) => void | Promise; 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); }