Created
October 2, 2025 03:03
-
-
Save renoirb/d02dc2613739300f6d7af49bdab2ab74 to your computer and use it in GitHub Desktop.
Stashed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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