/** * — segmented icon-button radio for the canvas view mode. * * Renders one button per mode; the currently-selected mode is marked with * `aria-pressed="true"`. Clicking a different button switches and emits * `mode-change` { detail: { mode } }. * * Mode keys: 'fit-width' | 'fit-height' | 'one-to-one'. */ const VIEW_MODES = [ { key: 'fit-width', label: 'Fit Width', icon: 'fa-arrows-left-right' }, { key: 'fit-height', label: 'Fit Height', icon: 'fa-arrows-up-down' }, { key: 'one-to-one', label: '1:1', icon: 'fa-vector-square' }, ]; class ViewModeControls extends HTMLElement { #mode = 'fit-width'; connectedCallback() { this.#render(); this.addEventListener('click', this.#onClick); } get mode() { return this.#mode; } set mode(value) { if (!VIEW_MODES.find(m => m.key === value)) return; if (this.#mode === value) return; this.#mode = value; this.#render(); } #onClick = (e) => { const btn = e.target.closest('button[data-mode]'); if (!btn) return; e.stopPropagation(); if (btn.dataset.mode === this.#mode) return; this.#mode = btn.dataset.mode; this.#render(); this.dispatchEvent(new CustomEvent('mode-change', { detail: { mode: this.#mode } })); }; #render() { const buttons = VIEW_MODES.map(m => ` `).join(''); this.innerHTML = `
${buttons}
`; } } customElements.define('view-mode-controls', ViewModeControls);