• HTML

    my-counter.html html

    <my-counter count="42">
    	<p>
    		Count: <span class="count"></span><br>
    		Parity: <span class="parity"></span>
    	</p>
    	<button type="button" class="decrement">−</button>
    	<button type="button" class="increment">+</button>
    </my-counter>
    CSS

    my-counter.css css

    my-counter {
    	display: flex;
    	gap: 0.5rem;
    	margin-block: 1rem;
    
    	p {
    		display: inline-block;
    		margin: 0;
    		flex: 1;
    	}
    
    	span {
    		margin-right: 0.5rem;
    	}
    
    	button {
    		padding: 0.25rem 0.5rem;
    		flex: 0;
    	}
    }
    
    TS

    my-counter.ts ts

    import { asInteger, setText, UIElement } from '../../../'
    
    export class MyCounter extends UIElement<{ count: number }> {
    	static localName ='my-counter'
    	static observedAttributes = ['count']
    
    	init = {
            count: asInteger(),
        }
    
    	connectedCallback() {
            super.connectedCallback()
    
    		// Event handlers
    		this.first('.increment').on('click', () => {
    			this.set('count', v => ++v)
    		})
    		this.first('.decrement').on('click', () => {
    			this.set('count', v => --v)
    		})
    
    		// Effects
    		this.first('.count').sync(setText('count'))
    		this.first('.parity').sync(setText(() => this.get('count') % 2 ? 'odd' : 'even'))
        }
    }
    MyCounter.define()