Skip to content

Instantly share code, notes, and snippets.

@renoirb
Created October 2, 2025 03:03
Show Gist options
  • Save renoirb/d02dc2613739300f6d7af49bdab2ab74 to your computer and use it in GitHub Desktop.
Save renoirb/d02dc2613739300f6d7af49bdab2ab74 to your computer and use it in GitHub Desktop.
Stashed
// fully-introspectable-component.mjs
/**
* A component that implements the full introspection API
*/
export class FullyIntrospectableComponent extends HTMLElement {
/**
* Attributes to observe for changes
*/
static get observedAttributes() {
return ['title', 'expanded', 'variant'];
}
/**
* Components that this element depends on
*/
static get dependentElements() {
return Object.freeze({
'value-date': 'https://dist.renoirb.com/esm/main/value-date-element/v1.0.0/browser.mjs',
'notice-box': 'https://dist.renoirb.com/esm/main/notice-box-element/v0.2.0/browser.mjs'
});
}
/**
* Events that this element emits
*/
static get emittedEvents() {
return Object.freeze([
{
name: 'expanded-change',
bubbles: true,
composed: true,
detailType: 'boolean',
description: 'Fired when the expanded state changes'
},
{
name: 'item-selected',
bubbles: true,
composed: false,
detailType: 'string',
description: 'Fired when an item is selected'
}
]);
}
/**
* Slots that this element defines
*/
static get definedSlots() {
return Object.freeze([
{
name: 'header',
required: false,
description: 'Content for the header area'
},
{
name: 'footer',
required: false,
description: 'Content for the footer area'
},
{
name: '', // Default slot
required: true,
description: 'Main content'
}
]);
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<div class="container">
<div class="header">
<slot name="header"></slot>
</div>
<div class="content">
<slot></slot>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
</div>
`;
}
connectedCallback() {
this.addEventListener('click', this.handleClick);
}
disconnectedCallback() {
this.removeEventListener('click', this.handleClick);
}
handleClick = () => {
const isExpanded = this.hasAttribute('expanded');
this.toggleAttribute('expanded', !isExpanded);
// Emit event
this.dispatchEvent(new CustomEvent('expanded-change', {
bubbles: true,
composed: true,
detail: !isExpanded
}));
}
// Rest of component implementation...
}
// Export as default
export default FullyIntrospectableComponent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment