• HTML

    accordion-panel.html html

    <accordion-panel>
    	<details open aria-disabled="true">
    		<summary class="visually-hidden">
    			<div class="summary">Tab 1</div>
    		</summary>
    		Content for Tab 1
    	</details>
    </accordion-panel>
    <accordion-panel>
    	<details aria-disabled="true">
    		<summary class="visually-hidden">
    			<div class="summary">Tab 2</div>
    		</summary>
    		Content for Tab 2
    	</details>
    </accordion-panel>
    <accordion-panel>
    	<details aria-disabled="true">
    		<summary class="visually-hidden">
    			<div class="summary">Tab 3</div>
    		</summary>
    		Content for Tab 3
    	</details>
    </accordion-panel>
    CSS

    accordion-panel.css css

    accordion-panel {
    	display: block;
    
    	> details {
    
    		& summary {
    			cursor: pointer;
    			font-size: var(--font-size-m);
    			font-weight: var(--font-weight-bold);
                margin: 0 0 var(--space-s);
    		}
    
    		::marker,
    		::-webkit-details-marker {
    			color: var(--color-text-soft);
    		}
    
    		.summary {
    			display: inline-block;
    			margin-left: var(--space-xs);
    		}
    
    		&[open] {
    			margin-bottom: var(--space-m);
    		}
    
    		&[aria-disabled="true"] {
    			
    			& summary {
    				pointer-events: none;
    				display: block;
    				cursor: text;
    			}
    
    			::marker,
    			::-webkit-details-marker {
    				display: none;
    			}
    
    			.summary {
                    margin-left: 0;
                }
    		}
    	}
    }
    TS

    accordion-panel.ts ts

    import { asBoolean, setProperty, toggleAttribute, UIElement } from "../../../"
    
    export class AccordionPanel extends UIElement<{
    	open: boolean,
        collapsible: boolean,
    }> {
    	static readonly localName = 'accordion-panel'
    	static observedAttributes = ['open', 'collapsible']
    
    	init = {
            open: asBoolean,
            collapsible: asBoolean
        }
    
    	connectedCallback() {
    		super.connectedCallback()
    
    		// Handle open and collapsible state changes
    		this.self.sync(
    			toggleAttribute('open'),
    			toggleAttribute('collapsible'),
    			setProperty('hidden', () => !this.get('open') && !this.get('collapsible'))
    		)
    
    		// Control inner details panel
    		this.first<HTMLDetailsElement>('details').sync(
    			setProperty('open'),
    			setProperty('ariaDisabled', () => String(!this.get('collapsible')))
    		)
    	}
    }
    AccordionPanel.define()